Java VM이 몇 개의 스레드를 지원할 수 있습니까?


212

Java VM이 몇 개의 스레드를 지원할 수 있습니까? 이것은 공급 업체에 따라 다릅니 까? 운영 체제에 의해? 다른 요인?

답변:


170

이것은 사용중인 CPU, OS, 다른 프로세스가 수행중인 작업, 사용중인 Java 릴리스 및 기타 요인에 따라 다릅니다. 컴퓨터를 종료하기 전에 Windows 서버에> 6500 스레드가있는 것을 보았습니다. 물론 대부분의 스레드는 아무것도하지 않았습니다. 기계가 약 6500 스레드 (Java에서)에 도달하면 전체 기계에 문제가 발생하여 불안정 해졌습니다.

내 경험에 따르면 Java (최신 버전)는 컴퓨터 자체가 문제없이 호스팅 할 수있는만큼 많은 스레드를 행복하게 사용할 수 있습니다.

물론 충분한 RAM이 있어야하며 스레드가 수행하는 모든 작업을 수행하고 각 스레드에 대한 스택을 갖기 위해 충분한 메모리로 Java를 시작해야합니다. 최신 CPU (가장 최근 몇 세대의 AMD 또는 Intel) 및 1-2 기가 메모리 (OS에 따라 다름)가있는 모든 시스템은 수천 개의 스레드가 있는 JVM을 쉽게 지원할 수 있습니다 .

이보다 더 구체적인 답변이 필요한 경우 가장 좋은 방법은 프로파일 링하는 것입니다.


86

음.

여기에는 몇 가지 매개 변수가 있습니다. 특정 VM뿐만 아니라 일반적으로 VM에 런타임 매개 변수도 있습니다. 그것은 운영 체제에 의해 다소 좌우됩니다. 기본 OS는 스레드에 대해 어떤 지원을 제공하며 스레드에 어떤 제한이 있습니까? VM이 실제로 OS 수준 스레드를 사용하는 경우 오래된 빨간색 스레드 / 녹색 스레드가 좋습니다.

"지원"의 의미는 또 다른 질문입니다. 다음과 같은 Java 프로그램을 작성하는 경우

   class DieLikeADog {
         public static void main(String[] argv){
             for(;;){
                new Thread(new SomeRunaable).start();
             }
         }
    }

(그리고 작은 구문 세부 사항에 대해 불평하지 않고, 나는 첫 번째 커피 한잔에 있습니다) 그렇다면 수백 또는 수천 개의 스레드가 실행될 것으로 예상해야합니다. 그러나 스레드 작성 은 상대적으로 비싸며 스케줄러 오버 헤드가 심할 수 있습니다. 그 스레드가 유용한 것을 할 수 있는지 확실하지 않습니다.

최신 정보

알았어 저항 할 수 없었어 여기 몇 가지 장식이 포함 된 작은 테스트 프로그램이 있습니다.

public class DieLikeADog {
    private static Object s = new Object();
    private static int count = 0;
    public static void main(String[] argv){
        for(;;){
            new Thread(new Runnable(){
                    public void run(){
                        synchronized(s){
                            count += 1;
                            System.err.println("New thread #"+count);
                        }
                        for(;;){
                            try {
                                Thread.sleep(1000);
                            } catch (Exception e){
                                System.err.println(e);
                            }
                        }
                    }
                }).start();
        }
    }
}

Intel의 OS / X 10.5.6 및 Java 6 5 (주석 참조)에서 얻을 수있는 내용은 다음과 같습니다.

새 스레드 # 2547
새 스레드 # 2548
새 스레드 # 2549
스레드를 만들 수 없습니다 : 5
새 실 # 2550
"main"스레드 예외 java.lang.OutOfMemoryError : 새 기본 스레드를 작성할 수 없습니다
        java.lang.Thread.start0 (기본 메소드)
        java.lang.Thread.start (Thread.java:592)에서
        DieLikeADog.main (DieLikeADog.java:6)에서

10
JVM을 얼마나 많은 메모리로 시작 했습니까? 중요합니다.
Eddie

10
Java 6 업데이트 13, Ubuntu 8.10 32 비트, 4Gig 램, 기본 JVM 설정 = 6318 스레드
Steve K

9
스레드 스택 크기로 재생하십시오. java -Xss100k를 사용하면 Linux에서 19702 개의 스레드를 만들 수있었습니다.
Steve K

21
java -Xss50k는 약 32k 스레드를 얻었습니다. 그것은 나의 4gigs의 램을 maxxed했다. Java를 죽일 수있는 새로운 프로세스를 포크하기 위해 내 컴퓨터에서 충분한 메모리를 다시 얻기 위해 실행중인 프로세스를 중단해야했습니다.)-좋은 시간.
Steve K

21
Windows 7에서 Java 7을 사용하여 시스템이 죽기 전에 200,000 개의 스레드를 만들었습니다. 작업 관리자는 8GB의 RAM을 사용하는 프로세스를 보여주었습니다. 그래도 왜 멈추었는지 모르겠습니다 ... 컴퓨터에 12GB의 RAM이 있습니다. 따라서 이것은 다른 한계에 도달했을 수 있습니다.
Dobes Vandermeer

50

Charlie Martin의 게시물을 읽은 후 힙 크기가 만들 수있는 스레드 수에 차이가 있는지 궁금해했으며 결과에 완전히 혼란 스러웠습니다.

Vista Home Premium SP1에서 JDK 1.6.0_11을 사용하여 2MB에서 1024MB 사이의 다양한 힙 크기로 Charlie의 테스트 응용 프로그램을 실행했습니다.

예를 들어, 2MB 힙을 작성하려면 인수 -Xms2m -Xmx2m으로 JVM을 호출합니다.

내 결과는 다음과 같습니다.

2 mb --> 5744 threads
4 mb --> 5743 threads
8 mb --> 5735 threads
12 mb --> 5724 threads
16 mb --> 5712 threads
24 mb --> 5687 threads
32 mb --> 5662 threads
48 mb --> 5610 threads
64 mb --> 5561 threads
96 mb --> 5457 threads
128 mb --> 5357 threads
192 mb --> 5190 threads
256 mb --> 5014 threads
384 mb --> 4606 threads
512 mb --> 4202 threads
768 mb --> 3388 threads
1024 mb --> 2583 threads

예, 힙 크기가 중요합니다. 그러나 힙 크기와 최대 스레드 수의 관계는 반비례합니다.

이상하다.


11
각 스레드에 해당 크기의 힙이 제공되면 의미가 있습니다.
Thorbjørn Ravn Andersen

1
경고 : 내 컴퓨터에는 2583GB의 RAM이 없습니다. 또는 교체하십시오. 그리고 JVM은 스레드 로컬 힙 공간을 할당하지 않습니다. 그렇게 할 수 없습니다 ...
benjismith

49
힙 크기는 스택에 사용 가능한 주소 공간을 줄입니다. 256K / 스택의 주소 공간이 의미가 있습니다.
Tom Hawtin-tackline

1
Aye, 이것은 같은 것을 보여줍니다 pequenoperro.blogspot.com/2009/02/less-is-more.html
Toby

39

이 질문이 꽤 오래되었지만 내 결과를 공유하고 싶습니다.

내 노트북은 25,000스레드 를 생성하는 프로그램을 처리 할 수 있으며 모든 스레드는 2 초 간격으로 MySql 데이터베이스에 일부 데이터를 씁니다.

나는이 프로그램을 실행 10,000 threads하기위한 30 minutes continuously등, 다른 프로그램을 종료 한 후도 내 시스템이 안정적이고 나는 브라우징, 개방과 같은 다른 일반적인 작업을 할 수 있었다

25,000 threads시스템 slows down그러나 반응 남아있다.

50,000 threads시스템 stopped responding즉시 내가 수동으로 시스템을 다시 시작했다.

내 시스템 정보는 다음과 같습니다.

Processor : Intel core 2 duo 2.13 GHz
RAM : 4GB
OS : Windows 7 Home Premium
JDK Version : 1.6

실행하기 전에 jvm argument를 설정했습니다 -Xmx2048m.

도움이 되길 바랍니다.


2
스와핑과 같은 "느리게"소리.
Thorbjørn Ravn Andersen 2015 년

감사. 꽤 견고한 머신이었고 갑자기 부팅이 멈출 때까지 거의 8 년 동안 제대로 작동했습니다. 방금 Windows 대신 Ubuntu를 설치하고 다시 숫자를 찾기 시작했습니다. :)
Shekhar

우분투 조미료와 튀긴 코어 2 듀오 : D
Pasupathi Rajamanickam

31

절대 이론적 인 최대는 일반적으로 프로세스의 인 스레드 스택 크기로 나눈 사용자 주소 공간 (모든 메모리는 스레드 스택을 위해 예약되어있는 경우 현실에서, 당신이 ... 작동하는 프로그램을하지 않지만).

예를 들어 32 비트 Windows에서는 각 프로세스에 2GB의 사용자 주소 공간이 있고 각 스레드에 128K 스택 크기가 부여되는 경우 최대 16384 개의 스레드 (= 2 * 1024 * 1024 / 128)를 기대할 수 있습니다. 실제로 XP에서 약 13,000을 시작할 수 있습니다.

그런 다음, 당신이 있는지 여부에 필수적이라고 생각 (가) 당신이 많은 코드에서 스레드가 아닌 (예 : 다음 ...가는 notifyAll ()를 호출 동일한 개체에 그들에게 모든 대기를 만들기로) 분명 어리석은 일을 할 것을 저글링을 관리 할 수 있습니다, 그리고 (b) 운영 체제가 할 수 있는지 여부. 원칙적으로, (a)에 대한 답변이 "예"이면 (b)에 대한 답변은 "예"입니다.

또한 Thread 생성자에서 스택 크기를 지정할 수 있습니다 . 이를 위해 VM 매개 변수를 망칠 필요가 없습니다.


1
따라서 64 비트 OS를 사용하십시오. 지금까지 64 비트 프로세서를 얼마나 오랫동안 사용 했습니까?
Tom Hawtin-tackline

물론, 나는 이론적 대 실제 한계의 예를 제시하고 있습니다. 아직도 32 비트 머신 (서버 포함)이 많이 있습니다.
Neil Coffey

2

Clojure의 이야기를 듣고 수천 개의 코어 (9000?)가있는 전시회에서 특정 기계에서 자신의 앱 중 하나를 실행해야한다고 들었습니다. 불행히도 현재 링크를 찾을 수 없습니다 (도움말?).

이를 바탕으로 하드웨어와 코드가 JVM이 아닌 제한 요소라고 말하는 것이 안전하다고 생각합니다.


다시 볼 수 있습니까? 나는 그것을보고 싶다-흥미롭게 들리고 기능적 언어가 코어 전체에 확장하기 쉽다는 것을 지원한다.
Thorbjørn Ravn Andersen

그것에 대한 링크를 제공 할 수 있습니까? Azul Systems의 수석 엔지니어 인 Cliff Click Jr.는 Azul의 가장 큰 JCA 시스템 (Azul Vega 3 Series 7300 모델 7380D : AzulSystems.Com/products/compute_appliance_specs.htm )에서 864 코어 및 768로 Rich Hickey의 Ant Colony Simulation을 실행했음을 알고 있습니다. GB RAM과 700 개의 개미는 700 개의 코어를 최대로 관리했습니다. 그러나 9000 코어는 꽤 인상적입니다. 어떤 기계였습니까?
Jörg W Mittag

그것은 내가 믿는 "Ants"시뮬레이션이었다-여기에 Rich Hickey (Clojure creator)가 이것에 대해 이야기하는 링크가 있습니다 -blip.tv/clojure/clojure-concurrency-819147 . Clojure가 멀티 코어 동시성을 처리하는 방법을 보여주기 위해 주로 800 개 이상의 코어가있는 큰 Azul 시스템 상자에있었습니다.
mikera

@mikera lins가 만료되었습니다.
Thorbjørn Ravn Andersen 2015 년

2

Charlie의 DieLikeACode 클래스를 사용한 후 Java 스레드 스택 크기는 만들 수있는 스레드 수의 큰 부분 인 것 같습니다.

-Xss 설정 자바 스레드 스택 크기

예를 들어

자바 -Xss100k DieLikeADog

그러나 Java에는 Executor 인터페이스가 있습니다. 이를 사용하면 수천 개의 실행 가능한 작업을 제출할 수 있으며 실행자가 고정 된 수의 스레드로 해당 작업을 처리하게 할 수 있습니다.


13
이름을 DieLikeACat으로 지정할 수 있습니까? 당신이 그것을 실행할 때까지 죽거나 살아 있지 않을 것입니다.
Goodwine

집행관을 지적 해 주셔서 감사합니다. 사람들은 더 자주 사용해야합니다. 그러나 통신을 처리해야 할 때처럼 Runnable/가 Callable실제로 계속 실행되어야하는 경우에는 작동하지 않습니다 . 그러나 SQL 쿼리에는 완벽합니다.
Matthieu


0

최대 스레드 수는 다음 사항에 따라 다릅니다.

  • 마이크로 프로세서, RAM과 같은 하드웨어 구성.
  • 32 비트인지 64 비트인지와 같은 운영 체제
  • run 메소드 내부의 코드 run 메소드 내부의 코드가 크면 단일 스레드 객체에 더 많은 메모리 요구 사항이 있습니다.

  • 0

    최신 (시스템화 된) Linux 시스템에 대한 추가 정보.

    이 값에 대한 조정이 필요한 많은 자원이 있습니다 (예 : 최대 JVM 스레드 수를 늘리는 방법 (Linux 64 비트) ). 그러나 cgroup에서 pids.max를 설정하는 시스템화 된 "TasksMax"제한을 통해 새로운 제한이 적용됩니다.

    로그인 세션의 경우 UserTasksMax 기본값은 커널 한계 pids_max (일반적으로 12,288)의 33 %이며 /etc/systemd/logind.conf에서 무시할 수 있습니다.

    서비스의 경우 DefaultTasksMax 기본값은 커널 한계 pids_max의 15 % (보통 4,915)입니다. "systemctl edit"에서 TasksMax를 설정하거나 /etc/systemd/system.conf에서 DefaultTasksMax를 업데이트하여 서비스에 대해이를 무시할 수 있습니다.


    0

    2017 년 ... DieLikeADog 클래스.

    새 스레드 # 92459 "main"스레드 예외 java.lang.OutOfMemoryError : 새 기본 스레드를 작성할 수 없습니다.

    i7-7700 16GB 램


    외교 답변은 다양합니다. 6GB의 램으로 10278을 얻었습니다.
    jamie

    -4

    여러 스레드를 처리 할 수 ​​있습니다. 제한이 없습니다. 영화를 보거나 NetBeans를 사용하는 동안 다음 코드를 실행했으며 컴퓨터를 멈추지 않고 제대로 작동했습니다. 이 프로그램보다 더 많은 스레드를 유지할 수 있다고 생각합니다.

    class A extends Thread {
        public void run() {
            System.out.println("**************started***************");
            for(double i = 0.0; i < 500000000000000000.0; i++) {
                System.gc();
                System.out.println(Thread.currentThread().getName());
            }
            System.out.println("************************finished********************************");
        }
    }
    
    public class Manager {
        public static void main(String[] args) {
            for(double j = 0.0; j < 50000000000.0; j++) {
                A a = new A();
                a.start();
            }
        }
    }

    7
    나는 이것이 주석이 매우 늦다는 것을 알고 있지만, 많은 스레드를 시작하고 실행할 수있는 이유는 (정상적이고 합리적인 시스템 구성을 가정 할 때) 각 스레드가 기본적으로 출력에서 ​​한 줄을 출력하고 더 이상 이유가 없기 때문이라고 생각합니다. 존재하고 곧 종료되므로 자원의 지속적인 가용성이 보장됩니다.
    ucsunil

    @ucsunil 사실이 아닙니다. 코드를 잘못 읽은 것 같습니다. 방금 시도해 보았고 다른 스레드가 첫 번째 줄뿐만 아니라 이름도 인쇄하고 있습니다. 그것은 그들이 활동적임을 의미합니다. 가비지 수집이 참조되지 않은 스레드를 재활용한다고 생각했다면 그렇지 않습니다 . here .
    Evgeni Sergeev

    1
    그러나, 단지 잠시 후, main을 던질 것이다 OutOfMemoryError그것은 더 이상 스레드를 만들 수 없다는, 내 컴퓨터에서. 아마도 @AnilPal, 당신은 그것을 눈치 채지 못했습니다. main(..)메소드 에 다른 print 문을 포함 시켜 오류 발생 후 새 스레드 생성이 중단되는 시점을 명확하게 확인 하는 것이 좋습니다 .
    Evgeni Sergeev

    5
    놀라운 ... 실제 튜링 머신 의 발견 ... 무한한 자원.
    Josh
    당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
    Licensed under cc by-sa 3.0 with attribution required.