3

サードパーティ API からクラスのインスタンスを何千も作成する必要がある状況があります。新しいインスタンスごとに新しいスレッドが作成されます。スレッドが 1000 を超えると、OutOfMemoryError が発生し始めます。ただし、アプリケーションでは 30,000 のインスタンスを作成する必要があります。各インスタンスは常にアクティブです。アプリケーションは、8 GB の RAM を備えた 64 ビットの Linux ボックスにデプロイされ、アプリケーションで使用できるのは 2 GB のみです。

サード パーティのライブラリのしくみでは、新しい Executor フレームワークやスレッド プーリングを使用できません。

では、どうすればこの問題を解決できますか?

スレッド プールの使用はオプションではないことに注意してください。イベントをキャプチャするために、すべてのスレッドが常に実行されています。

Linux ボックスのサイン メモリ サイズは私の制御範囲ではありませんが、32 GB システムでアプリケーションに 25 GB を使用できるように選択した場合、問題は解決しますか?

上記のシナリオに最適な Java 設定はありますか?

システムは Oracle Java 1.6 64 ビットを使用します。

4

4 に答える 4

7

諦めて、別の方法を考えようと思います。デフォルトのスタック サイズは 512K です。30k スレッドの場合、スタック空間だけで 15G になります。2G に収まるようにするには、スタックを 64K 未満に削減する必要があります。これにより、すべての Thread オブジェクトまたは JVM 自体を含むヒープ用のメモリがゼロになります。

これは、1 つの JVM で多数の同時スレッドを実行するときに遭遇する可能性が高い最も明白な問題です。

于 2013-08-16T00:09:22.780 に答える
1

未処理の取得ごとにスレッドが必要な SNMP プロバイダーでも同じ問題がありました (一度に何万もの未処理の取得を実行したかったのです)。NIO が存在するようになったので、これをもう一度行う必要がある場合は、ライブラリを自分で書き直すだけです。

「Javaコード」や設定では解決できません。私の経験では、Windows は約 2 ~ 3000 スレッドで停止します (これは後のバージョンでは変更されている可能性があります)。これを行っているとき、驚いたことに、Linux がサポートするスレッドはさらに少ない (約 1000) ことに気付きました。

システムがスレッドの供給を停止すると、「メモリ不足」が発生することが予想される例外です。つまり、それだけだと確信しています。メモリが不足するずっと前に、この例外が発生し始めました。どうにかして Linux をハックしてサポートを増やすこともできるかもしれませんが、その方法はわかりません。

ここでは、並行パッケージを使用しても役に立ちません。「グリーン」スレッドに切り替えることができれば可能ですが、それには JVM の再コンパイルが必要になる可能性があります (コマンド ライン スイッチとして利用できればいいのですが、そうではないと思います)。

于 2013-08-16T00:38:34.647 に答える