148

"java.lang.OutOfMemoryError : unable to create new native Thread32k スレッド (ps -eLF| grep -c java) の後、8GB RAM VM で " を取得しています。

ただし、"top" and "free -m" shows 50% free memory available. JDk は 64 ビットで、HotSpot と JRockit の両方で試しました。サーバーには Linux 2.6.18 があります。

OS stack size (ulimit -s)また、微調整と最大プロセス(ulimit -u)制限、limit.confの増加も試みましたが、すべて無駄でした.

また、ヒープサイズの組み合わせをほとんどすべて試し、低くしたり、高くしたりしました。

アプリケーションを実行するために使用するスクリプトは

/opt/jrockit-jdk1.6/bin/java -Xms512m -Xmx512m -Xss128k -jar JavaNatSimulator.jar /opt/tools/jnatclients/natSimulator.properties

返信いただきありがとうございます。

/etc/security/limits.conf と ulimit を編集してみましたが、それでも同じです

[root@jboss02 ~]# ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 72192
max locked memory       (kbytes, -l) 32
max memory size         (kbytes, -m) unlimited
open files                      (-n) 65535
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 10240
cpu time               (seconds, -t) unlimited
max user processes              (-u) 72192
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited
4

15 に答える 15

15

負荷テスト中に同じ問題が発生しました。その理由は、JVM が新しい Java スレッドをさらに作成できないためです。以下はJVMソースコードです

if (native_thread->osthread() == NULL) {    
// No one should hold a reference to the 'native_thread'.    
    delete native_thread;   
if (JvmtiExport::should_post_resource_exhausted()) {      
    JvmtiExport::post_resource_exhausted(        
        JVMTI_RESOURCE_EXHAUSTED_OOM_ERROR | 
        JVMTI_RESOURCE_EXHAUSTED_THREADS, 
        "unable to create new native thread");    
    } THROW_MSG(vmSymbols::java_lang_OutOfMemoryError(), "unable to create new native thread");  
} Thread::start(native_thread);`

根本的な原因: JVMTI_RESOURCE_EXHAUSTED_OOM_ERROR (リソースが使い果たされた (メモリーが使い果たされたことを意味する)) または JVMTI_RESOURCE_EXHAUSTED_THREADS (スレッドが使い果たされた) 場合、JVM はこの例外をスローします。

私の場合、Jboss はリクエストを処理するにはあまりにも多くのスレッドを作成していますが、すべてのスレッドがブロックされています。このため、JVM はスレッドだけでなくメモリも使い果たします (各スレッドはメモリを保持しますが、各スレッドはブロックされているため解放されません)。

Java スレッド ダンプを分析したところ、約 61,000 のスレッドがいずれかの方法でブロックされており、これがこの問題の原因となっていることがわかりました。以下はスレッドダンプの一部です

"SimpleAsyncTaskExecutor-16562" #38070 prio=5 os_prio=0 tid=0x00007f9985440000 nid=0x2ca6 waiting for monitor entry [0x00007f9d58c2d000]
   java.lang.Thread.State: BLOCKED (on object monitor)
于 2015-12-22T00:45:31.107 に答える
9

作成しようとしているスレッドの数が OS で許可されていないか、JVM で何らかの制限に達している可能性があります。特に 32k のようなラウンド数の場合、何らかの制限が原因である可能性が非常に高くなります。

本当に 32k スレッドが必要ですか? 最近のほとんどの言語には、再利用可能なスレッドのプールに対する何らかのサポートがあります。Java にも何かが用意されていると確信しています (ExecutorServiceユーザー Jesper が言及したように)。おそらく、新しいスレッドを手動で作成する代わりに、そのようなプールからスレッドを要求できます。

于 2013-05-28T10:13:40.750 に答える
7

スレッド スタック サイズも見て、より多くのスレッドが作成されるかどうかを確認することをお勧めします。JRockit 1.5/1.6のデフォルトのスレッド スタック サイズは、Linux OS 上の 64 ビット VM で 1 MB です。32K スレッドでは、この要件を満たすために大量の物理メモリと仮想メモリが必要になります。

開始点としてスタック サイズを512 KBに減らしてみて、アプリケーションのスレッドを増やすのに役立つかどうかを確認してください。また、アプリケーション処理をより多くの物理マシンまたは仮想マシンに分割するなど、水平スケーリングを検討することもお勧めします。

64 ビット VM を使用する場合、実際の制限は、OS の物理メモリと仮想メモリの可用性、および ulimitc などの OS チューニング パラメータによって異なります。以下の記事も参考になると思います。

OutOfMemoryError: 新しいネイティブ スレッドを作成できません – 問題の解明

于 2013-08-28T13:39:36.100 に答える
4

top を bash で使用すると表示されないゴースト プロセスが原因で、同じ問題が発生しました。これにより、JVM がそれ以上のスレッドを生成できなくなりました。

私にとっては、すべての Java プロセスをjpsで一覧表示し(シェルで実行するだけ)、ゴースト プロセスごとに bash コマンドをjps使用して個別に強制終了したときに解決しました。kill -9 pid

これは、いくつかのシナリオで役立つ場合があります。

于 2017-07-25T14:15:17.867 に答える
3

このエラーは、次の 2 つの理由で発生する可能性があります。

  • 新しいスレッドを収容するための余地がメモリにありません。

  • スレッド数がオペレーティング システムの制限を超えています。

スレッド数が Java プロセスの制限を超えているとは思えません

したがって、おそらく問題はメモリが原因である可能性があります。考慮すべき点の1つは

スレッドは JVM ヒープ内には作成されません。それらは JVM ヒープの外部で作成されます。そのため、RAM の空き容量が少ない場合、JVM ヒープの割り当て後にアプリケーションで「java.lang.OutOfMemoryError: ネイティブ スレッドを作成できません」というエラーが発生します。

考えられる解決策は、ヒープ メモリを減らすか、RAM 全体のサイズを増やすことです。

于 2019-01-10T06:13:52.070 に答える
2

スレッドを作成しているプロセスを見つけるには、次を試してください。

ps huH

私は通常、出力をファイルにリダイレクトし、ファイルをオフラインで分析します (各プロセスのスレッド数が期待どおりかどうか)。

于 2018-02-16T18:54:49.117 に答える
2

java.lang.OutOfMemoryError: Unable to create new native threadJVM が OS に新しいスレッドを要求するたびに、に直面する可能性があります。基盤となる OS が新しいネイティブ スレッドを割り当てられない場合は常に、この OutOfMemoryError がスローされます。ネイティブ スレッドの正確な制限はプラットフォームに大きく依存するため、以下のリンクの例と同様のテストを実行して、これらの制限を確認することをお勧めします。ただし、一般に、原因となる状況java.lang.OutOfMemoryError: Unable to create new native threadは次の段階を経ます。

  1. JVM 内で実行されているアプリケーションによって新しい Java スレッドが要求された
  2. JVM ネイティブ コードは、新しいネイティブ スレッドを作成する要求を OS にプロキシします。 OS は、スレッドにメモリを割り当てる必要がある新しいネイティブ スレッドを作成しようとします。
  3. OS は、32 ビット Java プロセス サイズがメモリ アドレス空間を使い果たした (たとえば、(2-4) GB プロセス サイズ制限に達した) か、OS の仮想メモリが完全に使い果たされたために、ネイティブ メモリの割り当てを拒否します。
  4. java.lang.OutOfMemoryError: Unable to create new native thread エラーがスローされます。

参照: https://plumbr.eu/outofmemoryerror/unable-to-create-new-native-thread

于 2016-10-02T17:50:23.760 に答える
1

ノードの OutOfMemmory が原因でジョブが失敗している場合は、最大マップとレデューサーの数を微調整し、JVM がそれぞれを選択できます。mapred.child.java.opts (デフォルトは 200Xmx) は通常、データ ノード固有のハードウェアに基づいて増やす必要があります。

このリンクは役立つかもしれません...確認してください

于 2013-05-28T10:13:58.777 に答える
0

これと同じ問題があり、Java API の不適切な使用であることが判明しました。複数回初期化されるべきではないバッチ処理メソッドでビルダーを初期化していました。

基本的に私は次のようなことをしていました:

for (batch in batches) {
    process_batch(batch)
}

def process_batch(batch) {
    var client = TransportClient.builder().build()
    client.processList(batch)
}

私がこれをすべきだったとき:

for (batch in batches) {
    var client = TransportClient.builder().build()
    process_batch(batch, client)
}

def process_batch(batch, client) {
    client.processList(batch)
}
于 2016-06-14T01:15:15.697 に答える