こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

マルチスレッド処理で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がメモリを食いつぶしていることが原因ではないかと思うのですが、このような場合、どう解決すればいいのでしょうか。どなたかご教授いただけませんでしょうか・・お願いします。

投稿日時 - 2009-05-26 19:00:38

QNo.4992440

すぐに回答ほしいです

質問者が選んだベストアンサー

 こんにちは。

>えっと、これは各POPアカウントのすべてのメール受信の処理が完全に終わったら、
>次の処理へ移ると言う仕様でして、すべてのthreadの終了を判断できるように、
>ということで入れた処理なんですが、これは不要ですか??

 これでは、スレッドが同時実行されないので、マルチスレッドにしている意味がないのでは?

 同時実行する気がないのなら普通にシングルスレッドで実行すればよいですし、同時実行するのなら、ThreadPoolExecutorとかを使って、スレッド数をコントロールした方がいいんじゃないでしょうか?

投稿日時 - 2009-05-27 18:28:07

お礼

PecoPlusさん、ありがとうございます。ThreadPoolExecutorというものがあったんですね・・。初めて知りました。ご教授ありがとうございます。とりあえずそれを試してみようと思います。

投稿日時 - 2009-05-28 21:31:15

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(2)

ANo.1

たぶんPopGetThreadにメモリリーク(オブジェクトの未解放)があるんでしょうね。

もひとつ、forループにおけるthread.join()の意味がわかりませんが…。要らないのでは?

投稿日時 - 2009-05-26 19:50:58

補足

_ranco_さんありがとうございます。

たぶんPopGetThreadにメモリリーク(オブジェクトの未解放)があるんでしょうね。>>
それは、PopGetThread自身の未解放という意味でしょうか。それとも、PopGetThreadがパラメータとして持つ何か、と言う意味でしょうか。

forループにおけるthread.join()>>

えっと、これは各POPアカウントのすべてのメール受信の処理が完全に終わったら、次の処理へ移ると言う仕様でして、すべてのthreadの終了を判断できるように、ということで入れた処理なんですが、これは不要ですか??

投稿日時 - 2009-05-26 23:11:55

あなたにオススメの質問