- ベストアンサー
マルチスレッド処理でOutOfMemory
こんにちは。現在javaによるバッチ処理で、一定時間ごとにメールを受信してその内容を解析してDBに登録する、と言うプログラムを組んでいます。 メールの受信は、POPアカウントごとにサーバに接続して受信すると言う仕様にしなくてはなりません。このため、POPアカウントごとにThreadを生成して並行処理で複数のPOPサーバに同時に接続してメールを受信する、と言う流れにします。 ここで問題なのが、タイトルのとおり、OutOfMemorryエラーが発生してしまうことなんです。おそらくThreadの生成の仕方に問題があるのではないか、と言う考えにいたりましたが、解決策がわからないので、ここで質問させていただきます。以下が、そのコードを簡略化したものです。以下の一連の処理が一定時間ごとに行われる想定です。 ~中略~ // POPアカウント情報をリストへ格納 List popAccountList = getPopData(); for(int i = 0; i < popAccountList.size(); i++){ PopAccount data = popAccountList.get(i); // PopAccountの一意のIdをスレッドにセットして生成 PopGetThread thread = new PopGetThread(data.popData); // スレッドの中で、メール受信処理が行われる。 thread.start(); try{ // 1つのスレッドが処理を終えるまで待つ thread.join(); }catch(InterruptedException ie){ } } ~続く~ こういう具合で、この処理を一定時間ごと(分単位)に、繰り返します。Runtime.getRuntime.totalMemory()などで、確認すると、周期処理が進むごとに、徐々に使用メモリが増えていってしまい、やがてOutOfMemoryになります。Threadがメモリを食いつぶしていることが原因ではないかと思うのですが、このような場合、どう解決すればいいのでしょうか。どなたかご教授いただけませんでしょうか・・お願いします。
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
こんにちは。 >えっと、これは各POPアカウントのすべてのメール受信の処理が完全に終わったら、 >次の処理へ移ると言う仕様でして、すべてのthreadの終了を判断できるように、 >ということで入れた処理なんですが、これは不要ですか?? これでは、スレッドが同時実行されないので、マルチスレッドにしている意味がないのでは? 同時実行する気がないのなら普通にシングルスレッドで実行すればよいですし、同時実行するのなら、ThreadPoolExecutorとかを使って、スレッド数をコントロールした方がいいんじゃないでしょうか?
その他の回答 (1)
- _ranco_
- ベストアンサー率58% (126/214)
たぶんPopGetThreadにメモリリーク(オブジェクトの未解放)があるんでしょうね。 もひとつ、forループにおけるthread.join()の意味がわかりませんが…。要らないのでは?
補足
_ranco_さんありがとうございます。 たぶんPopGetThreadにメモリリーク(オブジェクトの未解放)があるんでしょうね。>> それは、PopGetThread自身の未解放という意味でしょうか。それとも、PopGetThreadがパラメータとして持つ何か、と言う意味でしょうか。 forループにおけるthread.join()>> えっと、これは各POPアカウントのすべてのメール受信の処理が完全に終わったら、次の処理へ移ると言う仕様でして、すべてのthreadの終了を判断できるように、ということで入れた処理なんですが、これは不要ですか??
お礼
PecoPlusさん、ありがとうございます。ThreadPoolExecutorというものがあったんですね・・。初めて知りました。ご教授ありがとうございます。とりあえずそれを試してみようと思います。