2017-03-06 75 views
0

我有一個包含數百萬條消息的大型郵箱。我只想學習每個問題,不管它是否有附件。 (不感興趣的大小,名稱,附件數量,只有真假是足夠的)。當我使用此代碼並使用Profiler工具進行監視時,我看到message.getContent()消耗內存並且沒有清除它。由於處理數百萬條消息,會發生內存不足問題。原因是,getContent()methot緩存一些數據並保留它。Java,IMAP,檢查消息是否具有附件而不提取

什麼是此代碼的替代品,而無需致電getContent? 或者我如何強制清除由getContent設置的緩存? 如何申請message.writeTo()這種情況?

//processing million message instances in a loop i=1, 1000000 

Multipart multiPart = (Multipart) message[i].getContent(); 
for (int i = 0; i < multiPart.getCount(); i++) { 
    MimeBodyPart part = (MimeBodyPart) multiPart.getBodyPart(i); 
    if (Part.ATTACHMENT.equalsIgnoreCase(part.getDisposition())) { 
        // yes, it has an attachment 
        return true; 
    } 
} 
return false; 
+0

也許你可以通過看到或看不見的消息來減少消息。示例:http://stackoverflow.com/questions/12988799/javamail-check-message-content-gmail-imap –

+0

因爲一些商業規則,我需要他們全部。我只提取標題(主題,來自等)並忽略正文,附件沒有任何內存或性能問題。但我只需要有附件或沒有。當用戶稍後選擇任何消息時,獲取正文和附件。 – benchpresser

回答

0

這是一個經典的java問題。一般的模式是

while(true) { 
    Something foo = new Something(); 
    processSomehow(foo); 
    someCollection.add(foo); 
} 
// at this point, all of the created objects remain reachable 

離開循環之後每富不使用,但他們都保持可達,所以JVM變得非常大。經典的解決方案不是保留對您不需要的東西的引用。在你的情況下,message陣列保持這種可達性。

+0

我的消息數組不是100萬條消息。我在1000個塊中處理它們並獲取1000條消息,處理,清空數組並繼續下一步。沒有完成getContent的調用時,不會發生內存問題。 – benchpresser

+1

IMAPFolder是/有這樣一個數組,所以你有一個,除非你關閉並重新打開該文件夾。不過,重新打開一個大文件夾是非常緩慢的。您可以通過調用[invalidateHeaders()](https://javamail.java.net/nonav/docs/api/com/sun/mail/imap/IMAPMessage.html#invalidateHeaders--)來減小每條消息的數量,從而減少很多比其文檔說的更多。也許這樣做,並重新開放每50萬條信息就夠了。 – arnt

+0

謝謝,我已經完成了今天的工作,每次關閉後都會釋放內存,問題似乎通過getContent解決。另一方面,我嘗試使用UID FETCH和BODYSTRUCTURE發送customprotocol命令,與getContent相比,內存使用量非常小,不需要打開/關閉文件夾。這兩種方法似乎都有效。 – benchpresser