7

私の Java Web アプリケーションには、Activiti ワークフロー エンジンと groovy スクリプト タスクを使用して非常に複雑なワークフローを実行するため、多くのスタック領域を必要とするバックグラウンド ワーカー スレッドが 1 つあります。

現在、StackOverflowErrors を回避するために、64 ビット Java および Tomcat で JVM Xss 設定を 16MB に設定する必要があります。エラーが発生した場合、スタック トレースは非常に巨大 (数百行) になりますが、すべてエンジン内で発生するため、私にはどうすることもできません。

今私の質問は: 実行時に単一のスレッドのスタック サイズを増やす方法はありますか?

アプリケーション内のすべてのスレッドの JVM のデフォルト Xss 設定を 512k に下げたいと思います。これで十分であり、16M でのみワーカーを実行します。

Java API は、Thread クラスのコンストラクターについて、このトピックに関するいくつかの情報を提供します。

public Thread(ThreadGroup group,
              Runnable target,
              String name,
              long stackSize)

しかし、動作は保証されておらず ([1])、Windows で動作するかどうかについての情報は見つかりませんでした。

また、1 つのスレッドのスタック スペースを増やすことができず、デフォルト値として 16MB を指定する必要がある場合、そのように高い設定を行うとどうなりますか? これは、すべての新しいスレッドが初期化時に 16MB のメモリを予約することを意味するのでしょうか (つまり、200 スレッド * 16MB: 3,2 GB)?

jconsole と taskmgr を見る限り、メモリ フットプリントは Xss 設定を増やしてからあまり変わっていないように見えますが、何かが足りないのかもしれません。

ヘルプや説明をいただければ幸いです。

[1]: http://docs.oracle.com/javase/6/docs/api/java/lang/Thread.html#Thread(java.lang.ThreadGroup , java.lang.Runnable, java.lang.String,長いです)

4

2 に答える 2

4

-XssHotSpot では、使用するサイズではなく、最大サイズを指定することに何の価値もありません。使用されるサイズは使用状況に基づいているため、これを不当に大きく指定すると、仮想メモリが無駄になりますが (32 ビット JVM では問題になる可能性があります)、物理メモリは無駄になりません。64 ビットの JVM を使用している場合、任意のスレッドを最大にしたいというデメリットはほとんどありません。

また、1 つのスレッドのスタック スペースを増やすことができず、デフォルト値として 16MB を指定する必要がある場合、そのように高い設定を行うとどうなりますか? これは、すべての新しいスレッドが初期化時に 16MB のメモリを予約することを意味するのでしょうか (つまり、200 スレッド * 16MB: 3,2 GB)?

各スレッドは、この量の仮想メモリを使用します。32 ビット JVM では、実際に使用するメモリが非常に少ない場合でも、アドレス空間が不足します。64 ビット JVM では、制限は TB にあり、実際に使用されるスタックのみがメイン メモリを使用します。

于 2012-07-16T15:44:45.110 に答える
0

関連するスレッドが非常に処理集約的である場合。このスレッドのロジックを別のアプリケーションとして実装し、キューを使用して情報を渡し、変数を処理します。必要に応じて、このアプリケーションのメモリ パラメータを増やすことができます。

ドキュメント リンクから:

仮想マシンは、stackSize パラメータを提案として自由に扱うことができます。指定された値がプラットフォームに対して不当に低い場合、仮想マシンは代わりにプラットフォーム固有の最小値を使用することがあります。指定された値が不当に高い場合、仮想マシンは代わりにプラットフォーム固有の最大値を使用することがあります。同様に、仮想マシンは、指定された値を自由に切り上げたり切り下げたりすることができます (または完全に無視することもできます)。

于 2012-07-16T15:13:14.700 に答える