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

このQ&Aに関連する最新のQ&A

A 回答 (2件)

 こんにちは。



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

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

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

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

お礼日時:2009/05/28 21:31

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



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

この回答への補足

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

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

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

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

補足日時:2009/05/26 23:11
    • good
    • 0

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Qアウト×デラックスでDr.あゆみがテキーラーなぎこに言ってた肝機能・・

2/2放送 番組概要は
ttp://o.x0.com/m/429875
です。

肝臓に良いサプリか、薬か分からないんですが、カタカナの6~7文字くらいの食べ物? が、肝臓に良いらしいお話をしていたらしいのですけど、体調不良の原因、たぶんそう(肝臓)だと思うのですが、いろいろ試してるけど中々改善してくれなくて、何なのか知りたくて、知ってたら教えてください。

Aベストアンサー

プラセンタがよいという話でしたよ。
http://datazoo.jp/tv/%E3%82%A2%E3%82%A6%E3%83%88%C3%97%E3%83%87%E3%83%A9%E3%83%83%E3%82%AF%E3%82%B9/1033394
https://ja.wikipedia.org/wiki/%E3%83%97%E3%83%A9%E3%82%BB%E3%83%B3%E3%82%BF

Qclass Test_A {  main(){}}の実行順序は?

public class Test_A {
public static void main(){

int a = 0;
int b = 1;

}
}
例えば上のようなサンプルで何故 main()がクラスTest_A の中に挟まっているのでしょうか?実行順序としては main()が終了したら、クラスTest_A の方はどうなるのでしょうか? main()からプログラムが始まるのは分かるのですが、その後の動作が分かりません。よろしくお願いします。 

Aベストアンサー

>main()がクラスTest_A の中に挟まっているのでしょうか

Javaは、全てのプロパティ、メソッドはどこかのクラスに属していないといけないからです。
mainメソッドであっても例外ではありません。

>main()からプログラムが始まるのは分かるのですが、その後の動作が分かりません。

これを考える上で最も重要なのはmainメソッドがstaticであることです。
staticなメソッドは、そのクラスのインスタンスを作らなくても、
つまり、new Test_A();としなくても実行することが可能です。
プログラム実行時には、Test_Aクラスのインスタンスは生成されません。
質問のコードでは変数a,bに値が代入され、それで終わりです。

Javaでは、(正確にはJavaVMは)実行するclassファイルにある、
String[]引数を持ったvoid mainメソッドを実行する仕様になっています。
しかし、mainメソッドを実行するときには何のインスタンスも生成されていないので、
何かのインスタンスのメソッドを実行することはできません。
なので、staticなメソッドでないとJavaVMが実行できないのです。
さらに、JavaVMからアクセス可能なスコープを与える必要があるので、
publicである必要もあるのです。

あとは、そのmainメソッドに指定されたコードを実行し、mainメソッドの最後まで処理が進んだら
そこでJavaVMが終了し、プログラムも終了します。

※細かい話ですが、main()からプログラムは始まりません。
正確に言うと、引数なしのmain()メソッドは他のメソッドと何ら代わりがありません。
プログラムを始めるには、
アクセススコープがpublicで、staticな戻り値のなく、引数にString配列を取るmainメソッド
であることが必要です。つまり、
public static void main(String[] args)
とするのが通常です。
試しに質問のコードをjavaコマンドで実行すると、NoClassDefFoundErrorが出るはずです。

>main()がクラスTest_A の中に挟まっているのでしょうか

Javaは、全てのプロパティ、メソッドはどこかのクラスに属していないといけないからです。
mainメソッドであっても例外ではありません。

>main()からプログラムが始まるのは分かるのですが、その後の動作が分かりません。

これを考える上で最も重要なのはmainメソッドがstaticであることです。
staticなメソッドは、そのクラスのインスタンスを作らなくても、
つまり、new Test_A();としなくても実行することが可能です。
プログラム実行時...続きを読む

Qリーチアウト(REACHOUT)というソフトって何?

先日、友人から「リーチアウト(REACHOUT)というソフト」の話を聞きました。このソフトを使うと、インターネットにつながっている自分のPCの中がのぞかれてしまうんですか? このソフトを搭載していなければ安心ですか? 搭載してあったらダメですか?

Aベストアンサー

リモートコントロールソフトです。
通常はサポートセンター業務やメンテナンス業務などに用いられます。
ご心配であればアンインストールすればよいのではないでしょうか?

参考URL:http://www.soliton.co.jp/products/reachout/

Q"try{}catch(){}"文で"close()"はどのように書けばよいのでしょうか。

こんにちは、片岡と言います。

プログラム1は、Java言語で学ぶデザインパターン入門(結城浩さん著)の
433ページを参考にして書きました。

私は、プログラム1のclose()の書き方よりもプログラム2のようなclose()の書き方が、
良いと思っています。
なぜならば、プログラム1では、out.writeObject(memento)行の例外によって、
close()が実行されないからです。

私のこの考え方は正しいのでしょうか。
もっと良いclose()の書き方はあるのでしょうか。
ご存知の方はいらっしゃいませんか。

●プログラム1
public class Main {
public static void saveMemento(Memento memento) {
try {
ObjectOutput out = new ObjectOutputStream(new FileOutputStream("game.dat"));
out.writeObject(memento);
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
… //以下略
}

public class Memento implements Serializable {
… //以下略
}


●プログラム2
public class Main {
public static void saveMemento(Memento memento) {
try {
ObjectOutput out = new ObjectOutputStream(new FileOutputStream("game.dat"));
out.writeObject(memento);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (out != null) {
try {
out.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
}
… //以下略
}

public class Memento implements Serializable {
… //以下略
}


なお、私の環境は以下の通りです。
OS: Microsoft Windows XP Professional SP2
開発環境:Eclipse 3.2.2
java: java version "1.4.2_13"

こんにちは、片岡と言います。

プログラム1は、Java言語で学ぶデザインパターン入門(結城浩さん著)の
433ページを参考にして書きました。

私は、プログラム1のclose()の書き方よりもプログラム2のようなclose()の書き方が、
良いと思っています。
なぜならば、プログラム1では、out.writeObject(memento)行の例外によって、
close()が実行されないからです。

私のこの考え方は正しいのでしょうか。
もっと良いclose()の書き方はあるのでしょうか。
ご存知の方はいらっしゃいませんか。

●プロ...続きを読む

Aベストアンサー

>私のこの考え方は正しいのでしょうか。
正しいです。質問者さんが書かれているやり方が一般的です。
念のため書いておきますが、outをtryの外で宣言しないとコンパイルが通りません。

まぁ、あくまでデザインパターンを学ぶための本ですから、細かなコーディングについて気にする必要はないでしょう(疑問を持つことは良いことですが)。

Qskype out(スカイプアウト)の使い方を教えてください

skype outクレジットを購入したのですが、
一般加入電話や携帯電話に電話がかけられません。
国番号を入れろと書いてあるので、
81-090-2672-××××(0を入れないでかけてもだめ)と入力しても、だめです。
また、86-10-6524-××××と中国にかけても、だめです。
何か初歩的なミスがあると思うのですが、お教えいただけたら助かります。よろしくお願いいたします。

Aベストアンサー

+81-90-2671-****
とやってみてください。

QA a = new A(){}; の構文の意味が分からない。

下記サイトのコードを読んでいて、

ResponseListener listener = new ResponseListener() {
//略
};

という書き方があったのですが、どういう意味になるのでしょうか?
インスタンスの作り方は単に

A a = new A();

だと思うのですが…。

http://www.snmp4j.org/doc/org/snmp4j/Snmp.html

Aベストアンサー

無名クラスと呼ばれるものよ。
私も良くやるわ。

ちなみに
A a = new A();
はできないわよ。
Aはインターフェースだからね。


上記の場合、正式に実装するなら、
ResponseListenerをimplementsした
MyResponseListener(仮名)を別途作成し、
それを
ResponseListener listener = new MyResponseListener();
とする必要があるわ。
でも、このMyResponseListenerは
今ここでしか使わない、他からまったく参照する必要のない
超ローカルなクラスなのよ。
このメソッドが終了すればGCにかけてもいいわけ。
そんな場合、わざわざクラスを1つ作る必要なくて
その場でちょちょいとやってしまうことができるのよ。
それが無名クラスっていう実装方法よ。

http://www.javaroad.jp/java_class15.htm

FileFilterやCompare、Runnableなんかで
他のクラスで再利用しないときは良くやるわ。

無名クラスと呼ばれるものよ。
私も良くやるわ。

ちなみに
A a = new A();
はできないわよ。
Aはインターフェースだからね。


上記の場合、正式に実装するなら、
ResponseListenerをimplementsした
MyResponseListener(仮名)を別途作成し、
それを
ResponseListener listener = new MyResponseListener();
とする必要があるわ。
でも、このMyResponseListenerは
今ここでしか使わない、他からまったく参照する必要のない
超ローカルなクラスなのよ。
このメソッドが終了すればGCにかけても...続きを読む

Q卓ミキ(アナログミキサー)のアウトについて

卓ミキ(アナログミキサー)のmain outとmonitor out、その他のアウトの違いを教えて下さい。
どういう使い分けすればいんでしょうか?

M BOX(Protools)への入力の際はメインアウトからですか?

Aベストアンサー

はじめまして♪

ミキサーと言う道具を、どのように利用するかは、使う人次第です。

メインでもモニターでもテープでも、どれでも利用可能です。

メインは、それこそメインフェーダーの操作で音量を変えますし、モニターは専用フェーダーが有ればそちらで、無い場合は機種に依りメインフェーダーと無関係だったりメインフェーダーと同期したりそれぞれ切り替えが出来たり。テープに関しても似た様な物です。

PA環境の場合、メインが本当の意味でメインのスピーカー、モニターが出演者への戻しスピーカー、と言う場合はテープ系を利用するのが一般的でしょう。

実際のPA(拡声)を行わない、宅録等でしたら、メイン/モニター どちらかをスピーカーへ、どちらかをインターフェースでも良いですね。

どちらが良いか? これは使い易い方が正解で、多くの場合はどっちでも大差がないと言う場合もあります。

QJavaScriptで【window.google={kHL:"ja"};】という記述はどういう意味?

JavaScriptで【window.google={kHL:"ja"};】という記述はどういう意味?


YOUTUBE日本語版
http://jp.youtube.com/
のHTMLソースを見ていたら、



<script type="text/javascript">
    window.google={kHL:"ja"};
</script>


という記述を目にしたのですがこれはどういう意味あいというか目的のものなのでしょうか?


教えていただければ幸いです。

Aベストアンサー

これは、window.googleに'kHL'というキー(値は'ja')を持つ連想配列を
作成しています。

JavaScriptでの連想配列は

var 変数名 = {
キー : '値',
キー : '値',
:,
キー : '値'
};

というような感じで作成します。
キーはダブルクォートまたはシングルクォートで囲まなくても
いいようです。

参考URL:http://javascriptist.net/docs/basic_hash.html,http://www.openspc2.org/JavaScript/kouza2007/array/hash/index.html

Qnslookup時のDNSサーバのタイムアウトについて

nslookupを実行し、外部サーバの逆引きレコードを引いた結果、
1回目はタイムアウトなのですが、2回目は成功します。
DNSサーバの動作として、これは正常なのでしょうか?
また、1回目にタイムアウトになってしまう原因には
どんなことが考えられるでしょうか?
ご教示の程、宜しくお願い致します。

以下、コマンド実行結果

> nslookup
Server: <host name of dns server>
Address: 192.168.1.1

> set type=ptr

> 216.91.93.202.in-addr.arpa  ★1回目
Server: <hostname of dns server>
Address: 192.168.1.1

DNS request timed out.
timeout was 2 seconds.
DNS request timed out.
timeout was 2 seconds.
*** Request to <hostname of dns server> timed-out


> 216.91.93.202.in-addr.arpa  ★2回目
Server: <hostname of dns server>
Address: 192.168.1.1

Non-authoritative answer:
216.91.93.202.in-addr.arpa name = d.top.vip.bbt.yahoo.co.jp

以下省略

というように、1回目はタイムアウト、
2回目はレコードを引くことができます。

nslookupを実行し、外部サーバの逆引きレコードを引いた結果、
1回目はタイムアウトなのですが、2回目は成功します。
DNSサーバの動作として、これは正常なのでしょうか?
また、1回目にタイムアウトになってしまう原因には
どんなことが考えられるでしょうか?
ご教示の程、宜しくお願い致します。

以下、コマンド実行結果

> nslookup
Server: <host name of dns server>
Address: 192.168.1.1

> set type=ptr

> 216.91.93.202.in-addr.arpa  ★1回目
Server: <hostname of dns server>
Ad...続きを読む

Aベストアンサー

mondaです。

提示いただいた named.conf を眺めて思ったのですが、
ルートヒントが最後になっています。

named.conf を先頭から評価していって、途中でなにか
エラーを起こして、ルートヒントにたどり着けなくて
timeout ってのもありそうです。
zone "." の宣言を option 直後に配置したら変化ある
でしょうか?

#でも、それなら named を起動するときになにか
#エラーを吐いてるよなぁ…
# /var/log/messages になにか痕跡があるかも。

ご指摘のように forwarder の定義を「前のほうに」
置いても効果あるかも知れません。

あるいは、この DNS が管理しているゾーンデータベース
の記述にどこか typo のような些細な間違いが存在して
いないでしょうか?
--

QThread.sleep()はすべてのスレッドを停止する?

Threadを継承したCarというインスタンスを5つ作ってstart()させたとします。
そのあと、クラスメソッドのThread.sleep(1000)をすると、すべてのThreadインスタンスが1秒止まるのかと思ったのですが、そうではないといわれました。

クラスメソッドのThread.sleep()は何をsleepさせるのでしょうか?

Aベストアンサー

実行中のスレッドと表現されると曖昧ですよね。
5本のスレッドが走ってるとすると、全て「実行中のスレッド」ととれますよね。

さて本題ですが、
Thread#sleepは、自身のスレッドを待機させます。
なので、Thread#sleepを呼び出されたスレッドのことですね。


人気Q&Aランキング