it-source

"198.1994.Out Of Memory Error : 새 네이티브 스레드를 만들 수 없습니다."

criticalcode 2022. 10. 20. 21:17
반응형

"198.1994.Out Of Memory Error : 새 네이티브 스레드를 만들 수 없습니다."

우리는 점점 더"java.lang.OutOfMemoryError : unable to create new native Thread" 32,000 스레드 이후의 8GB RAM VM (ps - eLF | grep - c java )

하지만,"top" and "free -m" shows 50% free memory availableJDK는 64비트이고 HotSpot과 JRockit에서 모두 시도되었습니다.서버에는 Linux 2.6.18이 탑재되어 있습니다.

우리도 노력했어OS stack size (ulimit -s)tweaking 및 max process(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

이는 예외명이 매우 시사하는 메모리 문제가 아니라 운영체제 리소스 문제입니다.네이티브 스레드(즉, 운영 체제에서 JVM에 사용할 수 있는 스레드 수)가 부족합니다.

이것은 드문 문제입니다.그렇게 많은 양을 필요로 하는 경우는 거의 없기 때문입니다.무조건적인 스레드가 많이 산란되어 있는데 끝나지 않는 스레드가 많이 있습니까?

가능하면 실행자의 제어 하에 콜 가능/실행 가능을 사용하도록 다시 쓰는 것을 고려해 보십시오.코드 제어가 용이한 다양한 동작을 가진 표준 실행 프로그램이 많이 있습니다.

(스레드 수가 제한되는 이유는 여러 가지가 있지만 운영체제에 따라 다릅니다.)

부하 테스트 중에 같은 문제가 발생했습니다.그 이유는 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(Resources expired(메모리 고갈)) 또는 JVMTI_RESOURCE_EXHAUSTED_THREADS(스레드 고갈)가 이 예외를 발생시킵니다.

제 경우 Jboss가 요구를 충족시키기에는 너무 많은 스레드를 만들고 있지만 모든 스레드가 차단되어 있기 때문에 JVM은 스레드뿐만 아니라 메모리와 함께 모두 소진됩니다(각 스레드는 메모리를 보유하고 있지만 각 스레드는 차단되어 있기 때문에 해제되지 않습니다).

61K에 가까운 스레드가 검출된 Java 스레드 덤프를 분석했습니다.이 때문에 이 문제가 발생하고 있습니다.다음은 스레드 덤프의 일부입니다.

"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)

systemd를 통해 jvm을 시작하는 경우 일부 Linux OS에서 프로세스당 maxTasks(실제로 스레드를 의미하는 작업)가 있을 수 있습니다.

이를 확인하려면 "service status"를 실행하여 maxTasks 제한이 있는지 확인할 수 있습니다.있는 경우 /etc/systemd/system.conf를 편집하고 설정을 추가하여 삭제할 수 있습니다.DefaultTasksMax=displays

OS가 작성하려는 스레드 수를 허용하지 않거나 JVM에서 어느 정도 한계에 도달했을 수 있습니다.특히 32k와 같은 반올림수라면, 한 가지 또는 다른 종류의 제한이 매우 유력한 원인이 됩니다.

정말 32K 스레드가 필요합니까?대부분의 현대 언어에는 재사용 가능한 스레드 풀이 어느 정도 지원되고 있습니다.Java에도 뭔가 준비되어 있을 것입니다(예:ExecutorService(사용자 Jesper가 언급했듯이).수동으로 새 스레드를 생성하는 대신 이러한 풀에서 스레드를 요청할 수 있습니다.

스레드 스택사이즈도 살펴보고 더 많은 스레드가 생성되는지 확인할 것을 권장합니다.JRockit 1.5/1.6의 기본 스레드 스택 크기는 Linux OS의 64비트 VM의 경우 1MB입니다.이 요건을 충족시키려면 32K 스레드에는 상당한 양의 물리 메모리 및 가상 메모리가 필요합니다.

시작점으로 스택 크기를 512KB로 줄이고 응용 프로그램에 더 많은 스레드를 만들 수 있는지 확인합니다.또한 애플리케이션 처리를 더 많은 물리 머신 또는 가상 머신으로 분할하는 등 수평적인 확장을 검토할 것을 권장합니다.

64비트 VM을 사용하는 경우 진정한 제한은 OS의 물리 및 가상 메모리의 가용성 및 ulimitc 등의 OS 조정 파라미터에 따라 달라집니다.또한 다음 기사를 참고하시기 바랍니다.

Out Of Memory Error: 새로운 네이티브 스레드를 만들 수 없습니다.문제가 명확해졌습니다.

top in bash 사용 시 ghost 프로세스가 나타나지 않아 동일한 문제가 발생하였습니다.이로 인해 JVM이 더 많은 스레드를 생성할 수 없었습니다.

저는 jps를 사용하여 모든 Java 프로세스를 나열하면 해결됩니다(그냥 실행).jps네 껍데기 안에)를 사용하여 그들을 개별적으로 죽였다.kill -9 pidghost 프로세스별로 bash 명령어를 사용합니다.

이것은 경우에 따라서는 도움이 될 수 있습니다.

이 에러는, 다음의 2개의 이유로 표면화될 가능성이 있습니다.

  • 메모리에는 새로운 스레드를 저장할 공간이 없습니다.

  • 스레드 수가 OS 제한을 초과합니다.

스레드 수가 Java 프로세스의 제한을 초과했는지 의심됩니다.

따라서 메모리 문제일 가능성이 있습니다.한 가지 고려해야 할 점은

스레드는 JVM 힙 내에 생성되지 않습니다.JVM 힙 외부에 생성됩니다.따라서 RAM에 남아 있는 공간이 적으면 JVM 힙 할당 후 응용 프로그램이 "java.lang"으로 실행됩니다.Out Of Memory Error: 새 네이티브 스레드를 만들 수 없습니다."

가능한 해결책은 힙 메모리를 줄이거나 전체 RAM 크기를 늘리는 것입니다.

넌 지금 이 상황을 직시할 기회가 있어java.lang.OutOfMemoryError: Unable to create new native threadJVM이 OS에서 새 스레드를 요구할 때마다 자동으로 실행됩니다.기본 OS가 새 네이티브 스레드를 할당할 수 없는 경우 이 Out Of Memory Error가 느려집니다.네이티브 스레드의 정확한 제한은 플랫폼에 따라 매우 다르므로 다음 링크 예시와 유사한 테스트를 실행하여 이러한 제한을 알아내는 것이 좋습니다.하지만, 일반적으로, 상황은java.lang.OutOfMemoryError: Unable to create new native thread는 다음 단계를 거칩니다.

  1. JVM 내에서 실행되는 응용 프로그램에 의해 새로운 Java 스레드가 요구됩니다.
  2. JVM 네이티브 코드는 OS에 대한 새로운 네이티브 스레드 작성 요청을 프록시합니다.OS는 스레드에 메모리를 할당해야 하는 새로운 네이티브 스레드를 작성하려고 합니다.
  3. 32비트 Java 프로세스 사이즈가 메모리 주소 공간을 다 써버렸거나 (2-4) GB 프로세스 크기 제한에 도달했거나 OS의 가상 메모리가 완전히 소진되었기 때문에 OS는 네이티브 메모리 할당을 거부합니다.
  4. java.lang.Out Of Memory Error:새 네이티브 스레드를 만들 수 없습니다. 오류가 발생했습니다.

참고 자료: https://plumbr.eu/outofmemoryerror/unable-to-create-new-native-thread

스레드를 만들고 있는 프로세스를 확인하려면 다음 작업을 수행합니다.

ps huH

보통 출력을 파일로 리다이렉트하여 파일을 오프라인으로 분석합니다(각 프로세스의 스레드 수가 예상대로인지 여부).

노드에서 OutOfMemory로 인해 작업이 실패하는 경우 최대 맵과 감소기 수를 확인할 수 있으며 JVM은 각 맵을 선택합니다.mapred.child.java.opts(기본값은 200Xmx)는 일반적으로 데이터 노드별 하드웨어에 따라 증가해야 합니다.

링크는 도움이 될 수 있습니다.체크

JBoss 구성에는 몇 가지 문제가 있습니다./opt/jrockit-jdk 1.6/bin/java - Xms512m - Xmx512m Xms 및 Xmx는 JBoss 메모리 사용량을 설정된 값으로 제한하고 있습니다.따라서 8Gb에서 서버에는 512M + 일부 추가 메모리 사용량에 제한이 있으므로 이 숫자를 자유롭게 사용할 수 있습니다.나쁜 코드에도 불구하고 실행할 수 있습니다.가능하면 코드를 고치는 것도 좋을 것 같아요.

나도 같은 문제가 1센트 안에 있었다.OS/Red Hat 머신사용자, 프로세스 또는 전체 제한에 대한 스레드 제한에 도달했습니다.

제 경우 사용자가 가질 수 있는 스레드 수에 제한이 있었습니다.확인할 수 있는 행, 최대 사용자 프로세스 수

ulimit -a

이 명령을 사용하면 실행 중인 스레드 수를 확인할 수 있습니다.

$ ps -elfT | wc -l

프로세스가 실행 중인 스레드 수를 얻으려면 다음 절차를 수행합니다(top 또는 ps aux를 사용하여 프로세스 pid를 얻을 수 있습니다).

$ ps -p <PROCESS_PID> -lfT | wc -l

/proc/sys/kernel/threads-max 파일은 스레드 수에 대한 시스템 전체의 제한을 제공합니다.루트 사용자는 이 값을 변경할 수 있습니다.

제한을 변경하려면(이 경우 4096 스레드로)

$ ulimit -u 4096

Red Hat/centO에 대한 자세한 내용은 http://www.mastertheboss.com/jboss-server/jboss-monitoring/how-to-solve-javalangoutofmemoryerror-unable-to-create-new-native-thread를 참조하십시오.

같은 문제가 발생했는데, 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)
}

system.d로 Java 앱을 시작하시겠습니까?이건 너 주려고 가져온 거야!

나는 최근에 비틀거렸다DefaultTasksMax[1]은(는) 어떤 이유로 기계에서 60으로 제한되었습니다.새로운 키 잠금 설치에는 충분하지 않습니다.

Keyclock이 크래시되다java.lang.OutOfMemoryError : unable to create new native Thread'60'에 도달하자마자 ('60'')ps -elfT | grep keycloak|wc -l).

솔루션

1. system.d 설정을 검색합니다.

systemctl show --property DefaultTasksMax

저 같은 경우에는.이 인쇄물60

2. 더 높은 가치 제공

editor /etc/systemd/system.conf

편집:

DefaultTasksMax=128

유사한 값을 설정할 수도 있습니다.TaskMax를 참조하십시오.[2]를 참조해 주세요.

3. 새로고침, 확인, 재시작

systemctl daemon-reload
systemctl show --property DefaultTasksMax
systemctl start keycloak

[1] https://www.freedesktop.org/software/systemd/man/systemd-system.conf.html

[2] https://www.freedesktop.org/software/systemd/man/systemd.resource-control.html

우선 OS/VM을 크게 탓하지 않고 많은 스레드를 만드는 코드를 작성한 개발자를 탓합니다.기본적으로 코드(또는 서드파티)의 어딘가에 많은 스레드가 제어 없이 생성됩니다.

스택 트레이스/코드를 주의 깊게 검토하고 생성되는 스레드 수를 제어합니다.일반적으로 앱에 대량의 스레드가 필요하지 않습니다. 스레드가 필요한 경우에는 다른 문제입니다.

언급URL : https://stackoverflow.com/questions/16789288/java-lang-outofmemoryerror-unable-to-create-new-native-thread

반응형