Java.Lang.OutOfMemoryError: 새 네이티브 스레드를 만들 수 없습니다.

Suraj P 2023년10월12일
  1. Java에서 새 네이티브 스레드 오류를 생성할 수 없음
  2. java.lang.OutOfMemoryError: 새 기본 스레드를 만들 수 없음을 해결하는 방법
  3. 결론
Java.Lang.OutOfMemoryError: 새 네이티브 스레드를 만들 수 없습니다.

이 기사에서는 Java에서 java.lang.OutOfMemoryError: 새 네이티브 스레드를 생성할 수 없음 오류에 대해 알아봅니다.

Java에서 새 네이티브 스레드 오류를 생성할 수 없음

Java로 구축된 대부분의 실제 응용 프로그램은 여러 가지 작업을 수행하는 많은 구성 요소가 있는 다중 스레드 특성을 가지고 있습니다. 이러한 작업은 더 나은 처리량을 위해 서로 다른 스레드에서 실행됩니다. 그러나 Java 애플리케이션이 생성할 수 있는 최대 스레드 수는 사용 중인 운영 체제(OS)에 따라 다릅니다.

따라서 운영 체제가 시스템 또는 OS 스레드라고도 하는 새 커널 스레드를 생성할 수 없을 때마다 JVM(Java Virtual Machine)에서 새 네이티브 스레드를 생성할 수 없음 오류가 발생합니다.

백엔드에서 다음 이벤트가 발생하여 이 오류가 발생합니다.

  1. JVM 내부의 프로그램/응용 프로그램이 운영 체제에 새 스레드를 요청합니다.
  2. JVM 네이티브 코드에 의해 새로운 커널 스레드를 생성하라는 요청이 OS로 전송됩니다.
  3. 운영 체제는 메모리 할당 단계와 관련된 새 스레드를 생성하려고 시도합니다.
  4. 가상 메모리가 OS에 의해 고갈되었거나 요청하는 Java 응용 프로그램에 의해 메모리 주소 공간이 고갈되었기 때문에 운영 체제가 메모리를 할당할 수 없습니다.
  5. 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 수준에서 설정을 변경하는 것이지만 이 해결책은 두 가지 이유로 실현 가능하지 않습니다.

  1. 첫째, OS 수준에서 재구성하는 것이 쉽지 않으며 권장하지도 않습니다.
  2. 둘째, 대부분의 경우 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 프레임워크를 사용하여 솔루션 또는 해결 방법을 살펴보았습니다.

작가: Suraj P
Suraj P avatar Suraj P avatar

A technophile and a Big Data developer by passion. Loves developing advance C++ and Java applications in free time works as SME at Chegg where I help students with there doubts and assignments in the field of Computer Science.

LinkedIn GitHub

관련 문장 - Java Error