2011-11-10 20 views
24

Zauważyłem, że moja aplikacja java (działa na tomcat6) spawnuje wiele wątków, które się nie kończą.Znajdowanie przyczyny oczekujących/wątków wątków

Więc stworzyłem zrzut wątek i zauważyłem, że istnieje mnóstwo wątków oczekujących, tak:

"pool-1-thread-22" prio=5 tid=101b4b000 nid=0x127122000 waiting on condition [127121000] 
    java.lang.Thread.State: WAITING (parking) 
    at sun.misc.Unsafe.park(Native Method) 
    - parking to wait for <6c340cee0> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) 
    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:156) 
    at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:1987) 
    at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:399) 
    at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:947) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:907) 
    at java.lang.Thread.run(Thread.java:680) 
    Locked ownable synchronizers: 
    - None 

Teraz pytanie brzmi: co to są te wątki czekają? Mam podejrzaną klasę, która wydaje się odradzać te wątki, ale nie wiem, co dokładnie sprawia, że ​​te wątki utknęły.

Czy jest coś, co mogę zrobić, aby znaleźć przyczynę tego problemu, z wyjątkiem rozerwania klasy po linii i monitorowania zachowania wątków?

+1

Um, blokują w kolejce. W szczególności 'LinkedBlockingQueue.take()', który blokuje w nieskończoność, gdy kolejka jest pusta. –

+1

Co to znaczy? Jaka jest kolejka i co robi ta metoda 'take()'? – Timo

+1

Erm, to twój kod ... nie jesteśmy medium. Właśnie mówię ci dokładnie, co mówi ci zrzut wątku. –

Odpowiedz

19

Na tomcat zwykle żądają wątków roboczych oczekujących na połączenie. Nic się nie martwić. Są gotowi obsłużyć 100 użytkowników łączących się jednocześnie z serwerem.

+0

To nie może być. Mogę jawnie kliknąć przycisk w mojej aplikacji, który spawnuje te wątki. Po kliknięciu pojawiają się te wątki.Po chwili wątki te zużywają tyle pamięci, że serwer ulega awarii. – Timo

+0

Jeśli wątek jest zablokowany (np. Czekając na kolejkę), nie może zużywać więcej pamięci - nie jest uruchomiony i nie może żądać żadnego. Jeśli cokolwiek, ich stosy mogą być dobrze stronicowane po odczekaniu i tak naprawdę zmniejszyć rzeczywiste użycie pamięci RAM. –

+5

Zgadzam się z @ptyx na ten temat. Prawdopodobnie kliknięcie przycisku w aplikacji powoduje wysłanie żądań do serwera Tomcat. Domyślam się, że masz złą konfigurację mówiąc Tomcat, że jest w stanie obsłużyć nieprzyzwoicie dużą liczbę żądań, ponieważ chcesz być przedsiębiorczy. Tomcat kontynuuje tworzenie nowego "Thread" w swoim "ThreadPoolExecutor", ponieważ nie osiągnął "corePoolSize". Ostatecznie powoduje awarię twojego serwera, ponieważ skonfigurowałeś dla dużej liczby wątków, ale nie masz wystarczającej ilości pamięci, aby przydzielić całą przestrzeń stosu potrzebną dla tych wątków. Ale to tylko moje przypuszczenie. –

6

Te wątki są częścią ThreadPool. Więcej szczegółowych informacji java.util.concurrent.ThreadPoolExecutor. Wątek czeka na Runnable/Callable, aby zostać przesłanym do puli. Na przykład

ExecutorService e = Executors.newFixedThreadPool(10); 

stworzy 10 wątków, które będą zdawać czekać aż

e.submit(new Runnable(){ 
    public void run(){ ...} 
}); 

Wtedy jeden wątek zostanie o tym powiadomiony i powołują się na to runnable. Do czego są używane, nie mogę powiedzieć. Musisz dowiedzieć się, co uruchomiło pulę wątków. Może jego obsługa żądań klientów do serwera aplikacji.

+0

Nie sądzę. Te wątki nie są naprawione. Są tworzone dynamicznie, gdy użytkownik wchodzi w interakcję z aplikacją. Po długim użytkowaniu są ich setki, a nie tylko 10. – Timo

+0

Sądzę, że będziesz musiał dowiedzieć się, co dzieje się po interakcji użytkownika. Każdy może tworzyć te wątki, jak widzisz w moim przykładzie. Jeśli dostarczysz nam więcej kodu, możemy pomóc. –