Java.Lang.OutOfMemoryError: 새 네이티브 스레드를 만들 수 없습니다.
이 기사에서는 Java에서 java.lang.OutOfMemoryError: 새 네이티브 스레드를 생성할 수 없음
오류에 대해 알아봅니다.
Java에서 새 네이티브 스레드 오류를 생성할 수 없음
Java로 구축된 대부분의 실제 응용 프로그램은 여러 가지 작업을 수행하는 많은 구성 요소가 있는 다중 스레드 특성을 가지고 있습니다. 이러한 작업은 더 나은 처리량을 위해 서로 다른 스레드에서 실행됩니다. 그러나 Java 애플리케이션이 생성할 수 있는 최대 스레드 수는 사용 중인 운영 체제(OS)에 따라 다릅니다.
따라서 운영 체제가 시스템 또는 OS 스레드라고도 하는 새 커널 스레드를 생성할 수 없을 때마다 JVM(Java Virtual Machine)에서 새 네이티브 스레드를 생성할 수 없음
오류가 발생합니다.
백엔드에서 다음 이벤트가 발생하여 이 오류가 발생합니다.
- JVM 내부의 프로그램/응용 프로그램이 운영 체제에 새 스레드를 요청합니다.
- JVM 네이티브 코드에 의해 새로운 커널 스레드를 생성하라는 요청이 OS로 전송됩니다.
- 운영 체제는 메모리 할당 단계와 관련된 새 스레드를 생성하려고 시도합니다.
- 가상 메모리가 OS에 의해 고갈되었거나 요청하는 Java 응용 프로그램에 의해 메모리 주소 공간이 고갈되었기 때문에 운영 체제가 메모리를 할당할 수 없습니다.
- JVM에서
새 네이티브 스레드를 생성할 수 없음
오류가 발생합니다.
더 잘 이해하기 위해 예를 살펴보겠습니다.
import java.util.concurrent.TimeUnit;
public class Test {
public static void main(String[] args) {
while (true) {
new Thread(() -> {
try {
TimeUnit.HOURS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
}
}
}
위의 코드에서는 무한루프를 이용하여 지속적으로 쓰레드를 생성하고 대기하게 하고 있는데, 한 시간 동안 쓰레드를 홀딩한 상태로 계속 생성하고 있기 때문에 곧 운영체제가 허용하는 최대 쓰레드 개수에 도달하게 됩니다.
java.lang.OutOfMemoryError: 새 기본 스레드를 만들 수 없음
을 해결하는 방법
이제 이 오류를 해결하는 방법이나 해결 방법이 있습니까?
한 가지 해결책은 허용되는 스레드 수를 늘리기 위해 OS 수준에서 설정을 변경하는 것이지만 이 해결책은 두 가지 이유로 실현 가능하지 않습니다.
- 첫째, OS 수준에서 재구성하는 것이 쉽지 않으며 권장하지도 않습니다.
- 둘째, 대부분의 경우 OS 스레드 제한과 관련이 없습니다. 프로그래밍 오류가 있기 때문에 오류가 발생합니다. 예를 들어, 위에서 작성한 프로그램에서 우리는 이상적인 방법이 아닌 무한 루프를 사용하여 계속해서 생성하고 있습니다.
또 다른 해결 방법은 ExecutorService
프레임워크를 사용하여 지정된 시간에 처리할 수 있는 스레드 풀의 스레드 수를 제한하는 것입니다.
예:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.stream.IntStream;
public class Test {
public static void main(String[] args) {
ExecutorService es = Executors.newFixedThreadPool(10);
Runnable tasks = () -> {
try {
TimeUnit.HOURS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
};
IntStream.rangeClosed(1, 15).forEach(x -> es.submit(tasks));
}
}
코드에서 우리는 최대 10개의 스레드를 가질 수 있는 고정 크기의 스레드 풀을 만든 다음 스레드를 한 시간 동안 기다리게 하는 Runnable
작업을 만들었습니다.
IntStream
을 사용하여 스레드 풀에 15개의 작업을 제출했으므로 10개는 제출되고 나머지 5개는 ExecutorService
대기열에 있게 됩니다.
결론
이 기사에서는 운영 체제가 새 커널 스레드를 생성할 수 없을 때 Java에서 새 네이티브 스레드를 생성할 수 없음
오류가 발생한다는 것을 배웠습니다. 또한 ExecutorService
프레임워크를 사용하여 솔루션 또는 해결 방법을 살펴보았습니다.