Ile wątków obsługuje Java VM? Czy zależy to od dostawcy? przez system operacyjny? inne czynniki?
Ile wątków obsługuje Java VM? Czy zależy to od dostawcy? przez system operacyjny? inne czynniki?
Odpowiedzi:
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.
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.
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)
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
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 threads
dla30 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 threads
systememslows down
ale pozostaje responsywny.
Z 50,000 threads
systemem stopped responding
natychmiast 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.
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.
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.
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.
Runnable
/ Callable
faktycznie musi działać w sposób ciągły, tak jak wtedy, gdy musi obsługiwać komunikację. Ale jest idealny do zapytań SQL.
Przynajmniej w systemie Mac OS X 10.6 32bit system operacyjny ma limit (2560). Sprawdź ten wątek przepełnienia stosu .
Maksymalna liczba wątków zależy od następujących rzeczy:
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
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();
}
}
}
main
wrzuci OutOfMemoryError
na 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.