2017-03-06 11 views
0

私は何百万ものメッセージの大きなメールボックスを持っています。私は添付ファイルを持っているかどうかにかかわらず、それぞれのmessgeについて学ぶだけです。 (興味のないサイズ、名前、添付ファイルの数、真の偽のみで十分です)。このコードを使用してプロファイラツールでモニタすると、message.getContent()がメモリを消費してクリアされないことがわかります。数百万のメッセージを処理するため、メモリ不足の問題が発生します。理由は、getContent()メトーがいくつかのデータをキャッシュして保持するからです。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の問題です。一般的なパターンは、それがループを出た後の各fooが使用されていない

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--)を呼び出します。そのドキュメントよりも多くのことが言えます。たぶんそれをやって、50kのメッセージを再オープンすれば十分です。 – arnt

+0

ありがとう、私はすでにこれをすでに済ませており、メモリはそれぞれの終了後にリリースされていますが、問題はgetContentで解決されたようです。一方、UID FETCHとBODYSTRUCTUREでcustomprotocolコマンドを送信しようとしましたが、メモリー使用量はgetContentと比較して非常に小さいため、フォルダを開く/閉じる必要はありません。両方の方法が機能するようです。 – benchpresser

関連する問題