Domanda

Di recente ho convertito un'applicazione Swing in Webstart. Il processo è stato piuttosto semplice, ma ho scoperto che dopo aver chiuso tutte le finestre, la JVM della mia applicazione non si è conclusa. Il dump del thread ha mostrato che ci sono un paio di thread non daemon, in particolare EDT, AWT di Swing e un paio di thread correlati a websart.

La strategia effettiva utilizzata è che ogni finestra incrementa un contatore quando viene creato e ne diminuisce uno quando viene chiuso. L'operazione di chiusura predefinita è DISPOSE_ON_CLOSE. Quando il contatore raggiunge lo zero, interrompo tutti i threadpools e rilascia tutte le risorse JNI.

Quando ho lanciato l'applicazione da un file bat (stessi JAR), è terminata correttamente quando tutte le finestre sono state chiuse, quindi ho pensato che il problema avesse a che fare con Webstart.

Ora le domande:

  1. Qualcuno può dirmi cosa sta succedendo esattamente? Perché Webstart lascia JVM zombi?
  2. Esiste un modo per rilasciare esplicitamente le risorse Webstart senza arrestare la JVM?
  3. Ho sempre avuto l'opinione che chiamare System.exit () incoraggia la pratica sciatta di non rilasciare le risorse e fare affidamento sul sistema operativo per ripulire dopo di te (il che può portare a brutte sorprese se riutilizzi il codice in seguito) ... mi sto perdendo qualcosa?

Vedi anche domanda di follow-up per rilevare se l'app è stata lanciata da Webstart.

È stato utile?

Soluzione

A causa di bug in WebStart, sì. WebStart avvia un "thread sicuro" per i propri scopi che interagiscono con l'EDT. Questo SecureThread impedisce la conclusione automatica del processo Java che ci si aspetterebbe quando tutte le risorse di Windows e AWT saranno eliminate.

Per maggiori informazioni consultare http://www.pushing-pixels.org/?p = 232

Altri suggerimenti

Il AWT EDT è di solito il colpevole. Da alcuni anni ha una certa logica di spegnimento quando non ci sono finestre non sovrapposte. Tuttavia, ci sono problemi ricorrenti con le perdite, anche nell'ambito dell'implementazione di AWT e Swing. Pertanto, consiglio vivamente di utilizzare System.exit nelle versioni di produzione (potresti voler lasciarlo fuori per alcuni test per rilevare le perdite).

Il thread WebStart dovrebbe essere tutto demone quando non sono presenti finestre di sistema (console, servizi javax.jnlp e altre finestre di dialogo).

Webstart avvia la finestra della console (potresti disabilitarla). La finestra della console viene utilizzata per visualizzare stdout / err del processo webstart nonché log / debug rudimentale, ma ha l'effetto collaterale di creare una finestra AWT / Swing di livello superiore. Poiché AWT / EDT termina solo quando viene eliminata la finestra ULTIMA, la finestra della console regge l'applicazione. Probabilmente dovresti chiamare System.exit () per essere sicuro al 100% che la tua applicazione esca (a meno che tu non possa garantire una certa configurazione client, console webstart disattivata)

Valuta di collegarti con jconsole e dai un'occhiata a cosa sta facendo la JVM.

Riscontro lo stesso problema con l'avvio Web. Se spengo la console Java, il processo non si blocca. Qualche ID bug conosciuto da Sun?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top