2009-12-22 62 views
0

java郵件API使用流嗎?我在哪裏可以得到源代碼來確認這一點。 我也嘗試使用原始和非原始模式發送郵件。在原始模式 我可以通過一個輸入流的MimeMessage構造:[/ B]使用java郵件的內存不足

new MimeMessage(session, doc.getBodyInputStream()); 

在非原始模式下,我必須做以下 由於可以有任意mime類型,所以我必須使用DataHandlerDataSource。由於DataSource接口合同提到每次調用getInputStream()時都會提供新的inputStream,因此我們需要將數據保留在byte[]之內,這將導致大型文檔或文檔導致OOM。有沒有辦法避免這種情況?

MimeMessage msg = new MimeMessage(session); 
byte[] bArr = doc.getBody(); 
ByteArrayInputStream ins = new ByteArrayInputStream(
    bArr != null && bArr.length > 0 ? bArr : "".getBytes()); 
msg.setDataHandler(new DataHandler(new ByteArrayDataSource(ins, mimeType))); 
+1

如果您在將附件保留在內存中時遇到問題,您認爲電子郵件網絡將如何處理它? – skaffman 2009-12-22 10:52:41

回答

0

關於OOM,一般你的郵件應不大於10MB,這反過來不應該比保持在字節數組中10MB以上。

這是一個理論問題嗎?或者你真的看到了這種情況?

如果你看到它發生了,那麼增加你的堆大小,因爲上面的代碼看起來或多或少是正確的。

0

是否有可能對身體轉儲到(臨時)文件,讓傾銷巴爾走出的範圍(或設置爲空),然後使用FileDataSource?

1

如果您只是處理單個郵件,或者在處理(和緩存!)幾封郵件後得到OOM,是否會發生問題?

增加堆的大小是一種選擇,但如果它只是增加了時間,直到你被接下來的OOM傷害,那麼你想想替代保持原始字節數組在內存中。

而且您應該使用ByteArrayDataSource(byte[] bArr, String type)構造函數,這樣可以防止在內存中複製完整的字節數組,因爲bArr只是按原樣存儲在DataSource中。其他構造函數以8k字節數組開頭,每次需要更多空間時將其大小擴大一倍 - 這會浪費大量內存並可能是問題的原因。 (source

+0

Ours是一個B2B產品,提供這種功能之一,是的,我明白ByteArrayDataSource(byte [] bArr,String類型)將只保留一個byte []的副本,但客戶端郵件大小爲1 Gig,我們把數據放在內存中而不是流式傳輸。 – 2009-12-23 11:20:15

+0

但ByteArrayDataSource將始終將字節數組數據存儲在內存中,並且如果它是從輸入流創建的,它將爲數據創建(並調整其大小)內部字節數組。 1 GByte郵件?哦,我的上帝... – 2009-12-23 11:49:44