Hej
Mam pytanie jak w temacie - jak spowodować najprościej crash JVM?
Wiem, że to niecodzienne pytanie ale mam taką potrzebę i bynajmniej nie dla kaprysu.
Jak ktoś chce mogę powiedzieć w jakim celu.
pozdrawiam
Hehe dzięki za odpowiedzi. Chodziło mi o taki maksymalny crash gdzie jest generowany plik hs_err.
Przeszukałem jeszcze raz internet i znalazłem takie dwie perełki:
Object[] o = null;
while (true) {
o = new Object[] {o};
}
PathDasher dasher = new PathDasher(null) ;
Generują dwa sliczne fatal errory-pierwszy EXCEPTION_STACK_OVERFLOW , a drugi EXCEPTION_ACCESS_VIOLATION.
Bugi są za słabe (przynajmniej te, które znalazłem). Troche czerwonego wypisze i tyle.
A potrzebuje tego do....zwalniania biblioteki natywnej. Otóż używam JNA i dll'ki, w której definiuje się
właśny komunikat-takie winapi co się podaje uchwyt okna i nr komunikatu, który bedzie rozpoznawany (tak, chodzi mi o aplikacje J2SE pisaną w Swing'u). Potem tworze metode callback i własną pętle komunikatów i wszystko działa...do momentu aż zamknę aplikację. W JNI poprzez użycie "przejsciowej" biblioteki jest możliwe deinicjalizowanie dll'ki. W Jna nie ma zwalniania biblioteki -i przeważnie jest wszystko ok (zgarnie ją w końcu GC) oprócz bibliotek, które generują/przetwarzają własne komunikaty. I tu dupa zbita bo nawet System.exit nie da rady. JVM chce zamknac aplikację, zamyka okno a w pamięci dalej jest dll'ka która chce słać komunikaty a tu nie ma już tego uchwytu do okna. I JVM walczy walczy kilka sekund aż w koncu pojawia się piekny Wingrozowy komunikat : Win32 error Code: 1400 co znaczy tyle co Invalid windows handle i zima. Ciężko sobie wyobraźić by użytkownik był zadowolony z takiego zamykania aplikacji.
I dlatego potrzebowałem czegoś prostego do wysypania JVM bo teraz już jest spokój - mam własną metodę zamykania - odłączam sockety, czyszcze do nulla obiekty zamykam pętle komunikatów, zamykam okno i........ PathDasher dasher = new PathDasher(null) ; :P
A tak btw jakie są następstwa dla całej JVM po takim czymś? GC w końcu poczysćie pozostałosći?
lipkerson napisał(a)
I dlatego potrzebowałem czegoś prostego do wysypania JVM bo teraz już jest spokój - mam własną metodę zamykania - odłączam sockety, czyszcze do nulla obiekty zamykam pętle komunikatów, zamykam okno i........ PathDasher dasher = new PathDasher(null) ; :P
A tak btw jakie są następstwa dla całej JVM po takim czymś? GC w końcu poczysćie pozostałosći?
Takie cos prosi sie co najmniej o memory leak i nie mysle tutaj o VM a raczej o tych DLL'ach i o natywnym kodzie samego JNA. Po ogolnym zapoznaniu sie z samym API, wydaje sie, ze taki kod powinien zdawac egzamin:
LibraryProxy proxy = (LibraryProxy)Native.loadLibrary(LIBRARY_NAME, LibraryProxy.class);
//... do some stuff with the DLL proxy
NativeLibrary nl = NativeLibrary.getInstance(LIBRARY_NAME);
if(nl != null) {
proxy = null;
nl.dispose();
}
@ucilala, System.exit() zabija proces. Po prostu robi bezczelnego killa :D Jeżeli masz natywne biblioteki na pokładzie to memory leak gwarantowany. System oczywiście zwolni później pamięć, bo odkryje, że nie ma procesu JVM , ale trochę to potrwa.
@ws
Dzięki za odpowiedz konstruktywną. Tak, jest prawdą że od już nie pamiętam jakiej wersji JNA
wprowadzono właśnie metodę dispose(), która w teorii zwalnia bibliotekę.
Pierwszy raz natknąłem się tutaj na to:
https://jna.dev.java.net/servlets/ReadMsg?list=users&msgNo=3661
Problem jest taki, ze (chyba) skuteczne to jest tylko dla bibliotek pozbawionych zależności - trochę głupio to brzmi bo każda biblioteka, która robi coś sensownego ma zależnosci z innymi bibliotekami.
Chodzi mi o to, ze ładując bibiotekę a.dll przez NativeLibrary, ona ładuje/korzysta z biblioteki b.dll , która to biblioteka przetwarza komunikaty. Jeżeli zrobię dispose() to tylko mogę zwolnić biblioteke którą sam załadowałem. Oczywiscie w a.dll też powinna być natywna metoda zwalniajaca b.dll ale niestety korzystam z takiej, w której tego rozwiazania nie ma.
Zaznaczam, ze tak sobie to tłumaczę bo po prostu u mnie nie działa zwalnianie. I tak, "zweruje" wszelkie odwołania,obiekty,referencję przed zastosowaniem metody. Nawet kiedyś pamiętam próbowałem ładowania dll'ki w swoim classloaderze i potem całe to wyzerować i liczyć że GC to zgarnie...bez skutku.
Koziołek napisał(a)
@ucilala, System.exit() zabija proces. Po prostu robi bezczelnego killa :D
Oczywiście, tylko w tym akurat przypadku jest różnica czy zrobisz exit(), który tylko PRÓBUJE zabić aktualną JVM i potem PRÓBUJE czyścić pamiec, czy też zabijesz proces w systemie - zwykłe ctrlaltdel i kill. Ten drugi realnie zabije proces i wszystkie wygasłe zależności oraz przeczysci pamięć.
No i jeszcze jest JPS (Java Virtual Machine Process Status Tool), którego dopiero próbuje zaimplementować w Javie a nie wywołac po prostu z linii poleceń. Czy ktoś ma jakieś doswiadczenia? Można tam sobie zrobić killa dowolnego procesu Java, tylko czy przypadkiem to nie jest "wierna kopia" system.exit() ?
@ws
Dziękuje ! Kod, który napisałeś działa.
Ja to testowałem na starszej wersji JNA w której jeszcze proces zwalniania biblioteki nie był dopracowany. Potem trochę minęło i zapomniałem o tym. A dzięki Tobie sobie o tym przypomniałem, spróbowałem na najnowszej wersji i działa.
Jeszcze raz wielkie dzięki bo sposób w wysypywaniem JVM może i był skuteczny ale mało elegancki.
Pozdrawiam