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.