Ile wątków obsługuje Java VM?


Odpowiedzi:


170

Zależy to od używanego procesora, systemu operacyjnego, działań innych procesów, używanego wydania Java i innych czynników. Widziałem, że serwer Windows ma> 6500 wątków przed obniżeniem komputera. Oczywiście większość wątków nic nie robiła. Gdy maszyna osiągnęła około 6500 wątków (w Javie), cała maszyna zaczęła mieć problemy i stała się niestabilna.

Z mojego doświadczenia wynika, że ​​Java (najnowsze wersje) może bez problemu zużywać tyle wątków, ile sam komputer może hostować.

Oczywiście musisz mieć wystarczającą ilość pamięci RAM i musisz uruchomić Javę z wystarczającą pamięcią, aby zrobić wszystko, co robią Wątki i mieć stos dla każdego wątku. Każda maszyna z nowoczesnym procesorem (ostatnie kilka generacji AMD lub Intel) i 1 - 2 gigabajty pamięci (w zależności od systemu operacyjnego) może z łatwością obsługiwać maszynę JVM z tysiącami wątków.

Jeśli potrzebujesz bardziej szczegółowej odpowiedzi, najlepiej postawić profil.


86

Um, dużo.

Tutaj jest kilka parametrów. Konkretna maszyna wirtualna, a na maszynie wirtualnej zwykle znajdują się również parametry czasu wykonywania. Jest to w pewnym stopniu zależne od systemu operacyjnego: jakie wsparcie zapewnia podstawowy system operacyjny dla wątków i jakie ograniczenia na nich nakłada? Jeśli maszyna wirtualna faktycznie używa wątków na poziomie systemu operacyjnego, stara dobra czerwona nić / zielona nić.

„Wsparcie” oznacza kolejne pytanie. Jeśli napiszesz program Java, który jest po prostu podobny

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

(i nie narzekam na małe szczegóły składni, jestem na pierwszej filiżance kawy), to na pewno powinieneś spodziewać się uruchomienia setek lub tysięcy wątków. Ale tworzenie Wątku jest stosunkowo drogie, a narzut harmonogramu może być intensywny; nie jest jasne, czy te wątki mogą zrobić coś pożytecznego.

Aktualizacja

Okej, nie mogłem się oprzeć. Oto mój mały program testowy z kilkoma ozdobami:

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();
        }
    }
}

W systemie OS / X 10.5.6 na platformie Intel i Java 6 5 (patrz komentarze) oto, co mam

Nowy wątek # 2547
Nowy wątek # 2548
Nowy wątek # 2549
Nie można utworzyć wątku: 5
Nowy wątek # 2550
Wyjątek w wątku „main” java.lang.OutOfMemoryError: nie można utworzyć nowego wątku rodzimego
        at java.lang.Thread.start0 (Metoda rodzima)
        at java.lang.Thread.start (Thread.java:592)
        na DieLikeADog.main (DieLikeADog.java:6)

10
Z jaką pamięcią uruchomiłeś JVM? To się liczy.
Eddie

10
Aktualizacja Java 6 13, Ubuntu 8.10 32 Bit, 4Gig ram, Domyślne ustawienia JVM = 6318 wątków.
Steve K,

9
Hej, graj z rozmiarem stosu nici. java -Xss100k pozwolił mi tworzyć wątki 19702 w Linuksie.
Steve K

21
java -Xss50k pomógł mi w 32k wątkach. To jednak zmaksymalizowało moje 4 koncerty pamięci ram. Musiałem zatrzymać niektóre uruchomione procesy, aby odzyskać wystarczającą ilość pamięci na moim komputerze, aby rozwidlić nowy proces, aby zabić Javę;) - dobre czasy.
Steve K,

21
Używając Java 7 na Windows 7, właśnie utworzyłem 200 000 wątków, zanim mój system zginął. Menedżer zadań pokazał proces przy użyciu 8 GB pamięci RAM. Nie jestem pewien, dlaczego się tam zatrzymał ... Mam 12 GB pamięci RAM na komputerze. Więc może to być inny limit.
Dobes Vandermeer

50

Po przeczytaniu postu Charliego Martina zastanawiałem się, czy rozmiar stosu ma jakiekolwiek znaczenie w liczbie wątków, które możesz utworzyć, i byłem całkowicie zaskoczony wynikiem.

Korzystając z JDK 1.6.0_11 na Vista Home Premium SP1, uruchomiłem aplikację testową Charliego z różnymi rozmiarami sterty, od 2 MB do 1024 MB.

Na przykład, aby utworzyć stertę o wielkości 2 MB, wywołałbym JVM z argumentami -Xms2m -Xmx2m.

Oto moje wyniki:

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

Tak, rozmiar sterty zdecydowanie ma znaczenie. Ale związek między rozmiarem stosu a maksymalną liczbą wątków jest INWERSYJNIE proporcjonalny.

Co jest dziwne


11
miałoby sens, gdyby KAŻDY wątek otrzymał stos tego rozmiaru.
Thorbjørn Ravn Andersen

1
Uwaga: moja maszyna nie ma 2583 GB pamięci RAM. Lub zamień. A JVM nie przydziela miejsca na lokalne sterty wątków. Więc to nie może być
koniec

49
Rozmiar sterty zmniejsza przestrzeń adresową dostępną dla stosów. Sensowna jest przestrzeń adresowa 256 K / stos.
Tom Hawtin - tackline


39

Wiem, że to pytanie jest dość stare, ale chcę się tylko podzielić swoimi spostrzeżeniami.

Mój laptop jest w stanie obsłużyć program, który się spawnuje 25,000 wątki, a wszystkie te wątki zapisują pewne dane w bazie danych MySql w regularnych odstępach 2 sekund.

Uruchomiłem ten program 10,000 threadsdla30 minutes continuously wtedy również mój system był stabilny i udało mi się zrobić inne normalne czynności jak przeglądanie, otwieranie, zamykanie innych programów, itd.

Z 25,000 threadssystememslows down ale pozostaje responsywny.

Z 50,000 threadssystemem stopped respondingnatychmiast i musiałem zrestartować system ręcznie.

Szczegóły mojego systemu są następujące:

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

Przed uruchomieniem ustawiam argument jvm -Xmx2048m.

Mam nadzieję, że to pomoże.


2
„Spowalnia” brzmi jak zamiana.
Thorbjørn Ravn Andersen

Dzięki. Była to dość solidna maszyna i działała dobrze przez prawie 8 lat, aż nagle przestała się uruchamiać. Właśnie zainstalowałem na nim Ubuntu zamiast Windowsa i znów zaczął się chrupać numery :)
Shekhar

Smażony duet 2 z przyprawami Ubuntu: D
Pasupathi Rajamanickam

31

Absolutne maksimum teoretycznego jest na ogół procesem w przestrzeni adresowej użytkownika podzielona przez wielkość wątek stosu (choć w rzeczywistości, jeśli wszystko twoja pamięć jest zarezerwowana dla stosy nici, nie będzie mieć program roboczy ...).

Na przykład w 32-bitowym systemie Windows, gdzie każdy proces ma przestrzeń adresową użytkownika wynoszącą 2 GB, co daje każdemu wątkowi rozmiar stosu 128 KB, można oczekiwać absolutnego maksimum 16384 wątków (= 2 * 1024 * 1024/128). W praktyce uznaję, że mogę zacząć około 13 000 w XP.

Następnie myślę, że zasadniczo zastanawiasz się, czy (a) możesz zarządzać żonglowaniem tyloma wątkami w kodzie i nie robić oczywiście głupich rzeczy (takich jak zmuszanie ich do oczekiwania na ten sam obiekt, a następnie wywoływanie powiadomieniaAll () ...), oraz (b) czy system operacyjny może. Zasadniczo odpowiedź na (b) brzmi „tak”, jeśli odpowiedź na (a) jest również „tak”.

Nawiasem mówiąc, możesz określić rozmiar stosu w konstruktorze wątku ; do tego nie musisz (i prawdopodobnie nie powinieneś) zadzierać z parametrami VM.


1
Więc użyj 64-bitowego systemu operacyjnego. Od jak dawna wszyscy używamy procesorów 64-bitowych?
Tom Hawtin - tackline

Jasne, podam tylko teoretyczny limit praktyczny. Pamiętaj, że wciąż istnieje wiele komputerów 32-bitowych (w tym serwerów) ...
Neil Coffey,

2

Pamiętam, jak usłyszałem przemówienie Clojure'a, podczas którego on mógł uruchomić jedną ze swoich aplikacji na jakiejś specjalistycznej maszynie na targach z tysiącami rdzeni (9000?) I załadował je wszystkie. Niestety nie mogę teraz znaleźć linku (pomoc?).

Na tej podstawie uważam, że można bezpiecznie stwierdzić, że sprzęt i kod są czynnikami ograniczającymi, a nie JVM.


mógłbyś jeszcze raz spojrzeć? Chciałbym to zobaczyć - brzmi interesująco i obsługuje łatwe do skalowania funkcjonalne języki w różnych rdzeniach.
Thorbjørn Ravn Andersen

Czy możesz podać link do tego? Wiem, że Cliff Click, Jr., główny inżynier z Azul Systems, przeprowadził symulację kolonii mrówek Richa Hickeya na największym systemie JCA Azul (Azul Vega 3 Series 7300 Model 7380D: AzulSystems.Com/products/compute_appliance_specs.htm ) z 864 rdzeniami i 768 GB RAM, a 700 mrówkom udało się maksymalnie 700 rdzeni. Ale 9000 rdzeni, to całkiem imponujące. Co to za maszyna?
Jörg W Mittag

Wierzę, że była to symulacja „Mrówek” - oto link, w którym Rich Hickey (twórca Clojure) mówi o tym - blip.tv/clojure/clojure-concurrency-819147 . Było to na niektórych dużych systemach Azul z ponad 800 rdzeniami, głównie po to, by zademonstrować, jak dobry jest Clojure w obsłudze wielordzeniowej współbieżności.
mikera

@mikera lins wygasł.
Thorbjørn Ravn Andersen

2

Po zabawie z klasą DieLikeACode Charliego wygląda na to, że rozmiar stosu wątków Java stanowi ogromną część liczby wątków, które można utworzyć.

-Xss ustaw rozmiar stosu wątków Java

Na przykład

java -Xss100k DieLikeADog

Ale Java ma interfejs Executora . Użyłbym tego, będziesz mógł przesłać tysiące zadań Runnable, a Executor przetworzy te zadania ze stałą liczbą wątków.


13
Czy możemy nazwać to DieLikeACat? nie będzie martwy ani żywy, dopóki go nie uruchomisz.
Goodwine,

Dziękujemy za wskazanie Executorów, ludzie powinni częściej z niego korzystać. Ale to nie zadziała, jeśli Runnable/ Callablefaktycznie musi działać w sposób ciągły, tak jak wtedy, gdy musi obsługiwać komunikację. Ale jest idealny do zapytań SQL.
Matthieu


0

Maksymalna liczba wątków zależy od następujących rzeczy:

  • Konfiguracja sprzętu, taka jak mikroprocesor, pamięć RAM.
  • System operacyjny, taki jak 32-bitowy czy 64-bitowy
  • Kod w metodzie uruchamiania. Jeśli kod w metodzie uruchamiania jest ogromny, wówczas obiekt o jednym wątku będzie wymagał więcej pamięci

  • 0

    Dodatkowe informacje o nowoczesnych (systemowych) systemach Linux.

    Istnieje wiele zasobów na temat wartości, które mogą wymagać ulepszenia (np. Jak zwiększyć maksymalną liczbę wątków JVM (Linux 64bit) ); jednak nowy limit jest narzucany poprzez systemowy limit „TasksMax”, który ustawia pids.max na grupie cgroup.

    W przypadku sesji logowania domyślna wartość UserTasksMax wynosi 33% limitu jądra pids_max (zwykle 12 288) i może zostać zastąpiona w /etc/systemd/logind.conf.

    W przypadku usług domyślna wartość DefaultTasksMax wynosi 15% limitu jądra pids_max (zwykle 4915). Możesz zastąpić go dla usługi, ustawiając TasksMax w „edycji systemctl” lub aktualizując DefaultTasksMax w /etc/systemd/system.conf


    0

    Rok 2017 ... klasa DieLikeADog.

    Nowy wątek # 92459 Wyjątek w wątku „main” java.lang.OutOfMemoryError: Nie można utworzyć nowego wątku macierzystego

    i7-7700 16 GB RAM


    Odpowiedzi na offcourse mogą się różnić. Mam 10278 z 6 GB pamięci RAM.
    jamie

    -4

    Możesz przetwarzać dowolną liczbę wątków; tu nie ma limitu. Uruchomiłem następujący kod podczas oglądania filmu i korzystania z NetBeans, i działał poprawnie / bez zatrzymywania maszyny. Myślę, że możesz zachować jeszcze więcej wątków niż ten program.

    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
    Wiem, że to komentarz jest bardzo późny, ale uważam, że powodem, dla którego mogłeś uruchomić i uruchomić wiele wątków, jest to, że (przy założeniu normalnych i rozsądnych konfiguracji systemu) każdy wątek zasadniczo drukuje jeden wiersz z wyjścia, a następnie nie ma już powodu, aby istnieje i zostaje zabity wkrótce potem, zapewniając w ten sposób ciągłą dostępność zasobów.
    ucsunil

    @ucsunil To nie prawda. Myślę, że źle odczytałeś kod. Właśnie próbowałem i różne wątki drukują nie tylko pierwszy wiersz, ale także ich nazwy. Co oznacza, że ​​są aktywni. Jeśli myślałeś, że wyrzucanie elementów bezużytecznych przetwarza wątki, do których nie ma odniesienia, tak nie jest, zobacz tutaj .
    Evgeni Sergeev

    1
    Jednak po krótkim czasie mainwrzuci OutOfMemoryErrorna mój komputer, mówiąc, że nie może tworzyć więcej wątków. Być może @AnilPal, nie zauważyłeś tego. Sugeruję włączenie do main(..)metody kolejnej instrukcji print , aby wyraźnie zobaczyć, kiedy przestaje tworzyć nowe wątki po zgłoszeniu błędu.
    Jewgienij Siergiejew

    5
    niesamowite ... odkrycie faktycznej maszyny Turinga ... nieskończone zasoby.
    Josh
    Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
    Licensed under cc by-sa 3.0 with attribution required.