Ho un programma Java che viene avviato tramite ProcessBuilder
da un altro programma Java. System.exit(0)
viene chiamato dal programma figlio, ma per alcuni dei nostri utenti (su Windows) il processo java.exe
associato al figlio non viene terminato. Il programma figlio non ha hook di chiusura, né ha un SecurityManager
che potrebbe interrompere System.exit()
dal termine della VM. Non riesco a riprodurre il problema da solo su Linux o Windows Vista. Finora, le uniche segnalazioni del problema provengono da due utenti di Windows XP e un utente di Vista, utilizzando due JRE diversi (1.6.0_15 e 1.6.0_18), ma sono in grado di riprodurre il problema ogni volta.Che cosa può far continuare a funzionare Java dopo System.exit()?
Qualcuno può suggerire motivi per cui la JVM non sarebbe riuscita a terminare dopo System.exit()
e quindi solo su alcune macchine?
Modifica 1: Ho ottenuto l'utente di installare il JDK in modo da poter ottenere un dump di thread dalla VM offensiva. Quello che l'utente mi ha detto è che il processo VM scompare da VisualVM non appena fa clic sull'elemento 'Esci' nel mio menu --- ma, secondo Task Manager di Windows, il processo non è terminato, e non importa quanto a lungo l'utente attende (minuti, ore), non termina mai.
Edit 2: mi hanno confermato ora che Process.waitFor()
nel programma principale non torna per almeno uno degli utenti che hanno il problema. Quindi, per riassumere: Il bambino VM sembra essere morto (VisualVM non lo vede nemmeno), ma il genitore vede ancora il processo come vivo e così fa Windows.
Se si tratta di un finalizzatore, allora non è uno nel nostro codice --- noi don' ne hoSono sicuro che il bambino è ancora in esecuzione, dal momento che vediamo due processi Java e l'utente non ha altri programmi sul suo sistema che usano Java. Speravo di evitare di chiedergli di installare il JDK in modo da poter usare jstack, ma ora penso che potrebbe essere il modo migliore di procedere. – uckelman
Ciò che intendevo dire del processo figlio è che sono rimasti dei fili? Sta ancora rispondendo all'input? Ha ancora le maniglie aperte? Ho più familiarità con Unix di Windows, ma so che i processi non vengono cancellati dal sistema operativo Unix fino a quando il processo padre non li raccoglie e penso che sia lo stesso su Windows. Solo perché appare in alto o TaskManager non significa che sia ancora attivo. Ovviamente, questo non spiega perché succede solo ad alcuni utenti ... –
Per impostazione predefinita i finalizzatori non vengono eseguiti all'uscita; vedi http://java.sun.com/javase/6/docs/api/java/lang/System.html#runFinalizersOnExit(boolean) –