12

このエラーのために、私は1日以上、読書とテストを行い、壁に頭をぶつけてきました。

Listener私はこのように見えると呼ばれるクラスにいくつかのJavaコードを持っています

ExecutorService executor = Executors.newFixedThreadPool(NTHREADS);
boolean listening = true;
int count = 0;
while (listening) {
    Runnable worker;
    try {
        worker = new ServerThread(serverSocket.accept()); // this is line 254
        executor.execute(worker);
        count++;
        logger.info("{} threads started", count);
    } catch (Exception e1){
        //...
    }
}

私はJVM設定-Xmx(1から15Gまで)と-Xss(104kから512Mまで)を微調整してきました。サーバーには24GBのRAMがありますが、プログラムをサポートするデータベースも実行する必要があります。

2〜20個のスレッドが作成された後(プログラムの他の場所にも数十個存在します)、エラーが発生します

Exception in thread "Thread-0" java.lang.OutOfMemoryError: unable to create new native thread
at java.lang.Thread.start0(Native Method)
at java.lang.Thread.start(Thread.java:657)
at java.util.concurrent.ThreadPoolExecutor.addWorker(ThreadPoolExecutor.java:943)
at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1325)
at xxx.Listener.run(Listener.java:254)

$java -version収量:

java version "1.6.0_24"
OpenJDK Runtime Environment (IcedTea6 1.11.1) (fedora-65.1.11.1.fc16-x86_64)
OpenJDK 64-Bit Server VM (build 20.0-b12, mixed mode)

これが発生すると、システムには常に大量の空きメモリがあり、他のプログラムは引き続き正常に実行されます。Javaが新しいスレッド用のメモリがなくなったと考える原因は何ですか?

更新: おそらくこれは私が思っていたよりも大きいです-私が使用したときにこのエラーを(1回だけ)得ることができました^C

OpenJDK 64-Bit Server VM warning: Exception java.lang.OutOfMemoryError occurred dispatching signal SIGINT to handler- the VM may need to be forcibly terminated

クライアントを強制終了しようとしたときにも同じことが起こりました(これもJavaで記述され、同じサーバーで実行されています。ファイルを読み取り、ソケットを介してサーバーに送信する単一のスレッドです)。 JVMが一方を他方に干渉させますが、まだ空きメモリがあり、スワップをまったく使用していない場合はどうなるでしょうか。サーバー-Xmx1G-Xss104kクライアント-Xmx10M

UPDATE2: perlForks::Superライブラリを放棄し、bashからクライアントを実行すると、サーバーがOOMEでクラッシュする前に、最大34スレッドを取得できるため、複数のクライアントを実行すると、サーバーに確実に影響がありましたが、同時に実行できるはずです。一度に34を超える(クライアントを数える場合は68)Javaスレッド。どのシステムリソースがより多くのスレッドの作成をブロックしていますか(つまり、どこで豚を見つける必要がありますか)?すべて(クライアント、サーバー、GC ...)が同時にメモリを使い果たしたとき、top私のCPUとメモリの使用量について次のように言います。

Cpu(s):  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:  24681040k total,  1029420k used, 23651620k free,    30648k buffers
Swap: 26836988k total,        0k used, 26836988k free,   453620k cached

UPDATE3:以下のhs_errorログは、私のJavaが64ビットではないことを示していますか?

# There is insufficient memory for the Java Runtime Environment to continue.
# Cannot create GC thread. Out of system resources.
# Possible reasons:
#   The system is out of physical RAM or swap space
#   In 32 bit mode, the process size limit was hit
# Possible solutions:
#   Reduce memory load on the system
#   Increase physical memory or swap space
#   Check if swap backing store is full
#   Use 64 bit Java on a 64 bit OS
#   Decrease Java heap size (-Xmx/-Xms)
#   Decrease number of Java threads
#   Decrease Java thread stack sizes (-Xss)
#   Set larger code cache with -XX:ReservedCodeCacheSize=
# This output file may be truncated or incomplete.
#
# JRE version: 6.0_24-b24
# Java VM: OpenJDK 64-Bit Server VM (20.0-b12 mixed mode linux-amd64 compressed oops)
# Derivative: IcedTea6 1.11.1
# Distribution: Fedora release 16 (Verne), package fedora-65.1.11.1.fc16-x86_64
4

4 に答える 4

11

あなたはmax user processesあなたの限界の使用を知るために、によって制限することができます:

ulimit -u

制限を変更するには:

/etc/security/limits.confセットで:

user soft nproc [your_val] 
user hard nproc [your_val]

十分でない場合は、他の構成を追加する必要がある場合があります。このリンクを参照してください。

注:OPは、編集の制限を説明するこのバグレポートをfedoraとcentosで見つけまし/etc/security/limits.confた。

于 2012-05-27T21:01:37.877 に答える
3

問題は、JVMが新しいスレッドにスタックメモリを割り当てることができないことに関連している可能性があります。皮肉なことに、この問題は、ヒープスペース(-Xmx)とスタックスペース(-Xss)を減らすことで解決できます。たとえば、ここで適切な説明を確認してください:http ://www.blogsoncloud.com/jsp/techSols/java-lang-OutOfMemoryError-unable-to-create-new-native-thread.jsp

于 2012-05-24T18:02:13.663 に答える
3

新しいスレッドのメモリが不足しているわけではなく、実際のスレッドが不足しています。システムがおそらくあなたを止めています:ユーザーが作成できるスレッドの数には制限があります。次のようにクエリできます。

cat /proc/sys/kernel/threads-max

同じマシン上の他のプロセスの影響を受ける可能性があることに注意してください。それらのプロセスも多くのスレッドを作成します。この質問が役立つかもしれません: Linuxのプロセスあたりのスレッドの最大数は?

于 2012-05-24T18:02:46.040 に答える
1

明確にするために:

にを提供しServerSocketますThread。そのソケットにデータを送信しますか?おそらく、スレッドコンテキスト内に多くのデータを保存します。Streamdataをに格納するパターンを探してくださいbyte[]

于 2012-05-25T19:53:54.780 に答える