“java.lang.OutOfMemoryError : 새 기본 언어를 사용할 수 없습니다”
"java.lang.OutOfMemoryError : unable to create new native Thread
32k 이후 8GB RAM VM 에서 "를 얻습니다 (ps -eLF | grep -c java)
그러나 "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
예외 이름에서 제안하는 것처럼 메모리 문제가 아니라 운영 자원 문제입니다. 기본 기능, 즉 운영 체제에서 JVM이 사용할 수있는 수가 부족합니다.
거의 필요하지 않기 때문에 드문 문제입니다. 거의 끝나지 않지만 끝나지 않는 곳에 무조건 스폰이 많습니까?
가능하다면 집행자의 통제하에 Callable / Runnables를 사용하여 다시 쓰는 것을 고려할 수 있습니다. 코드가 쉽게 제어 할 수있는 다양한 동작을 가진 표준 실행 프로그램이 있습니다.
(스레드 수가 제한되는 데 많은 수가 여러 이유가 있고 운영마다는 여러 가지 이유가 있습니다.)
로드 테스트 동일한 문제가 발생했습니다. 그 이유는 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은 메모리라고하는 것이 아니라 소진하는 것입니다.
하나에 의해 차단 되어이가 발생했습니다. 아래는 전형적인 기능의 일부입니다
"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)
운영상에서 생성되는 많은 수를 허용하지 않고 JVM에서 일부 한계에 도달 할 수 있습니다. 특히 32k와 같은 라운드 수이면 한 종류 또는 다른 종류의 한계가 범인 일 가능성이 섭니다.
정말로 32k 스레드가 필요합니까? 대부분의 현대 언어는 재사용 가능한 스레드 풀에 대해 일종의 지원을 제공합니다. Java도 ExecutorService
제스퍼 사용자가 언급했듯이. 수동으로 새 풀을 만드는 대신 이러한 풀에서 스레드를 요청할 수 있습니다.
스레드 스택 크기도 살펴보고 더 많은 스레드가 생성되는지 확인하는 것이 좋습니다. JRockit 1.5 / 1.6 의 기본 스레드 스택 크기 는 Linux OS에서 64 비트 VM의 경우 1MB입니다. 32K 스레드는이 요구 사항을 충족하기 위해 상당한 양의 물리적 및 가상 메모리가 필요합니다.
시작점으로 스택 크기를 512KB 로 줄이고 애플리케이션에 대한 더 많은 스레드를 만드는 데 도움이되는지 확인하십시오. 또한 수평 적 확장 (예 : 더 많은 물리적 또는 가상 머신에 걸쳐 애플리케이션 처리 분할)을 탐색하는 것이 좋습니다.
64 비트 VM을 사용할 때 실제 제한은 OS 물리적 및 가상 메모리 가용성과 ulimitc와 같은 OS 튜닝 매개 변수에 따라 달라집니다. 또한 다음 기사를 참조로 권장합니다.
OutOfMemoryError : 새 원시 스레드를 만들 수 없음 – 문제가 설명 됨
bash에서 top을 사용할 때 표시되지 않는 고스트 프로세스로 인해 동일한 문제가 발생했습니다. 이로 인해 JVM이 더 많은 스레드를 생성하지 못했습니다.
나를 위해 모든 자바 프로세스를 jps ( jps
셸에서 실행) 로 나열하고 kill -9 pid
각 고스트 프로세스에 대해 bash 명령을 사용하여 개별적으로 죽일 때 해결 되었습니다 .
이는 일부 시나리오에서 도움이 될 수 있습니다.
노드의 OutOfMemmory로 인해 작업이 실패하는 경우 최대 맵 및 감속기 수를 tweek 할 수 있으며 JVM은 각각을 선택할 수 있습니다. mapred.child.java.opts (기본값은 200Xmx)는 일반적으로 데이터 노드 특정 하드웨어에 따라 늘려야합니다.
이 링크 가 도움 이 될 수 있습니다 ... pls 확인
JBoss 구성에 몇 가지 문제가 있습니다. /opt/jrockit-jdk1.6/bin/java -Xms512m -Xmx512m Xms 및 Xmx는 JBoss 메모리 사용량을 구성된 값으로 제한하므로 8Gb에서 서버는 512M 만 사용합니다. + 자신의 목적을 위해 추가하고, 그 수를 늘리고, OS 및 거기에서 실행되는 다른 물건을 위해 일부를 남겨 두는 것을 잊지 마십시오. 불미스러운 코드에도 불구하고 실행될 수 있습니다. 가능하다면 코드를 수정하는 것도 좋을 것입니다.
java.lang.OutOfMemoryError: Unable to create new native thread
JVM이 OS에서 새 스레드를 요청할 때마다 직면 할 수있는 기회가 있습니다. 기본 OS가 새 기본 스레드를 할당 할 수 없을 때마다이 OutOfMemoryError가 발생합니다. 네이티브 스레드에 대한 정확한 제한은 플랫폼에 따라 매우 다르므로 아래 링크 예제와 유사한 테스트를 실행하여 이러한 제한을 알아내는 것이 좋습니다. 그러나 일반적으로 원인 java.lang.OutOfMemoryError: Unable to create new native thread
이 되는 상황 은 다음 단계를 거칩니다.
- JVM 내에서 실행되는 응용 프로그램에서 새 Java 스레드를 요청합니다.
- JVM 네이티브 코드는 OS에 대한 새 네이티브 스레드를 생성하도록 요청을 프록시합니다. OS는 스레드에 메모리를 할당해야하는 새 네이티브 스레드를 생성하려고합니다.
- OS는 32 비트 Java 프로세스 크기가 메모리 주소 공간을 고갈 시켰거나 (예 : (2-4) GB 프로세스 크기 제한에 도달 했음) 또는 OS의 가상 메모리가 완전히 고갈 되었기 때문에 기본 메모리 할당을 거부합니다.
- java.lang.OutOfMemoryError : 새 원시 스레드를 작성할 수 없음 오류가 발생합니다.
참조 : https://plumbr.eu/outofmemoryerror/unable-to-create-new-native-thread
스레드를 생성하는 프로세스를 찾으려면 다음을 시도하십시오.
ps huH
일반적으로 출력을 파일로 리디렉션하고 파일을 오프라인으로 분석합니다 (각 프로세스의 스레드 수가 예상대로인지 여부).
jvm이 systemd를 통해 시작되는 경우 일부 Linux OS에는 프로세스 당 maxTasks 제한 (실제로 작업은 스레드를 의미 함)이있을 수 있습니다.
"서비스 상태"를 실행하여이를 확인하고 maxTasks 제한이 있는지 확인할 수 있습니다. 있는 경우 /etc/systemd/system.conf를 편집하고 구성을 추가하여 제거 할 수 있습니다. DefaultTasksMax = infinity
나는 이와 동일한 문제가 있었고 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)
}
이 오류는 다음 두 가지 이유로 인해 나타날 수 있습니다.
메모리에 새 스레드를 수용 할 공간이 없습니다.
스레드 수가 운영 체제 한계를 초과합니다.
스레드 수가 Java 프로세스의 제한을 초과했는지 의심됩니다.
그래서 가능성이 문제는 기억 때문일 수 있습니다.
스레드는 JVM 힙 내에 생성되지 않습니다. JVM 힙 외부에서 생성됩니다. 따라서 RAM에 남은 공간이 적 으면 JVM 힙 할당 후 응용 프로그램이 "java.lang.OutOfMemoryError : 새 원시 스레드를 만들 수 없음"으로 실행됩니다.
가능한 해결책은 힙 메모리를 줄이거 나 전체 램 크기를 늘리는 것입니다.
우선 저는 OS / VM을 그렇게 탓하지 않을 것입니다. 오히려 너무 많은 Thread 를 생성하는 코드를 작성한 개발자입니다 . 기본적으로 코드 (또는 타사) 어딘가에 많은 스레드가 제어없이 생성됩니다 .
스택 추적 / 코드를주의 깊게 검토하고 생성되는 스레드 수를 제어합니다. 일반적으로 앱에는 많은 양의 스레드가 필요하지 않아야합니다. 필요한 경우 다른 문제입니다.
'IT' 카테고리의 다른 글
bcrypt의 .net 구현 (0) | 2020.07.28 |
---|---|
Java 스택 크기를 늘리는 방법은 무엇입니까? (0) | 2020.07.28 |
GoogleService를 초기화하지 (0) | 2020.07.28 |
Node.js에 대한 자연스러운 함수 작성 방법 (0) | 2020.07.28 |
상태 표시 줄이 캐시 된 시간이 없습니다. (0) | 2020.07.28 |