2011-12-19 6 views
5

C'è un modo per garantire che l'intero processo Java venga chiuso in caso di arresto anomalo di Hotspot?Come forzare l'esecuzione del processo Java sull'arresto dell'hotspot

Stiamo ospitando una libreria nativa in un processo Java di Windows remoto (java.exe), ai fini dell'isolamento del processo. Tuttavia, abbiamo scoperto che anche quando c'è un crash di hotspot, sebbene il thread principale "muoia" con un arresto di hotspot, il processo stesso non muoia. Dobbiamo ucciderlo in Task Manager.

Pensiamo che ciò potrebbe essere dovuto al fatto che la libreria nativa stessa crea i propri thread che mantengono in vita il processo.

Vogliamo che l'intero processo Java muoia se si verifica un arresto anomalo dell'hotspot.

Il nostro attuale lavoro è di avere un altro thread che sta leggendo l'output del processo generato (dobbiamo comunque leggere l'output della console per impedire il blocco del processo). Abbiamo modificato per guardare anche in modo esplicito per un incidente VM:

private static String HOTSPOT_CRASH = "# A fatal error has been detected by the Java Runtime Environment"; 

public void run() { 
    try { 
     BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); 
     String line; 
     do { 
      line = reader.readLine(); 
      if (line != null) { 
       logger.info(prefix + ": " + line); 
      } 
      if(line.contains(HOTSPOT_CRASH)) { 
       logger.error(String.format("FATAL Hotspot crash detected. Killing child process '%s'...", hostProcess)); 
       hostProcess.destroy(); 
      } 
     } while (line != null); 
     reader.close(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
} 

Ma questo è un hack: Se la JVM sa abbastanza per uscire che c'è stato un incidente, sarebbe molto meglio se potesse essere detto di Termina anche il processo corrente.

C'è un modo per farlo? Idealmente sarebbe una opzione da riga di comando per JVM.

+3

Un processo non può arrestarsi in modo parziale. Quasi sicuramente hai due processi lì. –

+0

problema interessante! un arresto anomalo è un arresto anomalo, quindi non è possibile fare molto se ciò accade. probabilmente creerei un monitor heartbeat (il bambino invia un messaggio ping al genitore, e il genitore invia il pong ogni pochi minuti). in assenza di battito cardiaco, esci. – aishwarya

+0

@Ingo - purtroppo l'ho pensato anch'io. Ma si scopre che stiamo subendo un arresto anomalo, ma il processo continua a bloccarsi. Solo una volta che lo uccidiamo in Task Manager lo fa davvero. –

risposta

0

Di solito, una VM uscirà quando è stato rilevato un errore fatale ma è possibile impedirlo nel codice. Ecco un paio di indizi:

  • Controllare il processo padre. Su Unix, un bambino può morire solo quando il genitore elabora il segnale SIGCHLD (che dice al genitore che il bambino è terminato, questo permette al processo padre di leggere il codice di uscita, per esempio).

    Assicurarsi di elaborare l'uscita e che si chiami waitFor() almeno una volta dopo la morte del bambino. Questo dovrebbe ripulire il processo figlio.

  • Cerca thread non daemon. Se si dispone di thread non daemon nell'applicazione Java, possono impedire l'uscita dalla VM.

    Ma un errore VM interromperà tutti i thread, quindi la mia ipotesi è che non si pulisce mai il processo figlio.

+0

Stiamo comunicando con il processo figlio su un socket TCP. Se il processo figlio rileva un errore di hotspot, vogliamo che il thread nel processo padre che sta leggendo dal socket ottenga un messaggio Connection-reset-by-peer. Una volta ottenuto ciò, possiamo ripulire il processo figlio. –

+0

Il problema al momento è che il processo genitore non ha modo di sapere che il processo figlio si è arrestato in modo anomalo: la chiamata "read" del socket attende solo per sempre, fino a quando non avremo terminato il processo in Task Manager. –

Problemi correlati