4

私は、さまざまなバンドルを持つプロジェクトに取り組んでいます。例を見てみましょう。5 つのバンドルがあり、それらのバンドルのそれぞれにメソッド名があるとしprocessます。

現在、process以下のマルチスレッド コードを使用して、これら 5 つのバンドルすべてのメソッドを並行して呼び出しています。

しかし、どういうわけか、以下のマルチスレッドコードを実行するたびに、常にメモリ不足の例外が発生します。しかし、プロセスメソッドを1つずつ呼び出して順番に実行している場合、メモリ不足の例外は発生しません。

以下はコードです-

public void callBundles(final Map<String, Object> eventData) {

    // Three threads: one thread for the database writer, two threads for the plugin processors
    final ExecutorService executor = Executors.newFixedThreadPool(3);

    final Map<String, String> outputs = (Map<String, String>)eventData.get(Constants.EVENT_HOLDER);

    for (final BundleRegistration.BundlesHolderEntry entry : BundleRegistration.getInstance()) {
        executor.submit(new Runnable () {
            public void run() {
                try {
                    final Map<String, String> response = entry.getPlugin().process(outputs);

                    //process the response and update database.
                    System.out.println(response);
                } catch (Exception e) {
                    e.printStackTrace();
                }               
            }
        });
    }
}

以下は例外です。マルチスレッドコードの上で実行しているときはいつでも取得しています。

JVMDUMP006I Processing dump event "systhrow", detail "java/lang/OutOfMemoryError" - please wait.
JVMDUMP032I JVM requested Heap dump using 'S:\GitViews\Stream\goldseye\heapdump.20130904.175256.12608.0001.phd' in response to an event
JVMDUMP010I Heap dump written to S:\GitViews\Stream\goldseye\heapdump.20130904.175256.12608.0001.phd
JVMDUMP032I JVM requested Java dump using 'S:\GitViews\Stream\goldseye\javacore.20130904.175256.12608.0002.txt' in response to an event
UTE430: can't allocate buffer
UTE437: Unable to load formatStrings for j9mm
JVMDUMP010I Java dump written to S:\GitViews\Stream\goldseye\javacore.20130904.175256.12608.0002.txt
JVMDUMP032I JVM requested Snap dump using 'S:\GitViews\Stream\goldseye\Snap.20130904.175256.12608.0003.trc' in response to an event
UTE001: Error starting trace thread for "Snap Dump Thread": -1
JVMDUMP010I Snap dump written to S:\GitViews\Stream\goldseye\Snap.20130904.175256.12608.0003.trc
JVMDUMP013I Processed dump event "systhrow", detail "java/lang/OutOfMemoryError".
ERROR: Bundle BullseyeModellingFramework [1] EventDispatcher: Error during dispatch. (java.lang.OutOfMemoryError: Failed to create a thread: retVal -1073741830, errno 12)
java.lang.OutOfMemoryError: Failed to create a thread: retVal -1073741830, errno 12

JVMDUMP006I Processing dump event "systhrow", detail "java/lang/OutOfMemoryError" - please wait.
JVMDUMP032I JVM requested Heap dump using 'S:\GitViews\Stream\goldseye\heapdump.20130904.175302.12608.0004.phd' in response to an event
JVMDUMP010I Heap dump written to S:\GitViews\Stream\goldseye\heapdump.20130904.175302.12608.0004.phd
JVMDUMP032I JVM requested Java dump using 'S:\GitViews\Stream\goldseye\javacore.20130904.175302.12608.0005.txt' in response to an event

私はJDK1.6.0_26EclipseにインストールされているJREとして使用しています。

4

2 に答える 2

2

を呼び出すたびにcallBundles()、独自のエグゼキューターを作成して新しいスレッドプールを作成します。各スレッドには独自のスタック スペースがあります。したがって、JVM を開始すると、最初の呼び出しで合計 3M のヒープ (1024k が 64 ビット JVM のデフォルトのスタック サイズ) を持つ 3 つのスレッドが作成され、次の呼び出しで別の 3M などが作成されます。1000 回の呼び出し/秒が必要になります。 3GB/秒!

2 番目の問題はshutdown()、エグゼキュータ サービスを作成しないことです。そのため、スレッドは、ガベージ コレクタがエグゼキュータを削除するまで存続します (finalize()も呼び出しますshutdown())。しかし、GC はスタック メモリをクリアすることはありません。したがって、スタック メモリに問題があり、ヒープがいっぱいでない場合、GC は役に立ちません。

10から30 ExecutorServiceスレッド、または 3 から 30 のThreadPoolExecutorキャッシュされたスレッドとLinkedBlockingQueue. shutdown()可能であれば、アプリケーションが停止する前にサービスを呼び出します。

アプリケーションの物理 RAM、負荷、および応答時間を確認して、パラメータのヒープ サイズ、最大スレッド、およびプール内のスレッドのキープ アライブ時間を調整します。コードの他のロック部分 (データベース接続プールのサイズなど) とサーバーの CPU/コアの数を調べてください。スレッド プール サイズの出発点は、CPU/コアの数に 1 を加えたものです。多くの I/O 待機があると、より有用になります。

于 2013-09-18T17:34:18.137 に答える