Esecuzione di jmap ottenendo Impossibile aprire il file socket


88

Ho dovuto correre jmapper prendere il dump del mio processo. ma jvmrestituito:

Unable to open socket file: target process not responding or HotSpot VM not loaded
The -F option can be used when the target process is not responding

Quindi ho usato -F:

./jmap -F -dump:format=b,file=heap.bin 10330
Attaching to process ID 10331, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 24.51-b03
Dumping heap to heap.bin ...
  1. L'uso -F va bene per prendere il dump dell'heap?
  2. Sto aspettando 20 minuti e non ho ancora finito. Qualche idea sul perché?

Risposte:


187

jmapvs. jmap -F, così come jstackvs. jstack -Futilizzare meccanismi completamente diversi per comunicare con la JVM di destinazione.

jmap / jstack

Quando si esegue senza -Fquesti strumenti, utilizzare il meccanismo di collegamento dinamico . Funziona come segue.

  1. Prima di connettersi al processo Java 1234, jmapcrea un file .attach_pid1234nella directory di lavoro del processo di destinazione o in /tmp.

  2. Quindi jmapinvia SIGQUITal processo di destinazione. Quando JVM cattura il segnale e lo trova .attach_pid1234, avvia il AttachListenerthread.

  3. AttachListenerthread crea un socket di dominio UNIX /tmp/.java_pid1234per ascoltare i comandi da strumenti esterni.

  4. Per motivi di sicurezza quando una connessione (da jmapè accettato), verifica JVM che le credenziali di peer presa sono pari a euide egiddi processo JVM. Ecco perché jmapnon funzionerà se eseguito da un utente diverso (anche da root).

  5. jmapsi connette al socket e invia il dumpheapcomando.

  6. Questo comando viene letto ed eseguito dal AttachListenerthread della JVM. Tutto l'output viene restituito al socket. Poiché il dump dell'heap viene eseguito direttamente da JVM, l'operazione è molto veloce. Tuttavia, JVM può farlo solo nei safepoint . Se non è possibile raggiungere un safepoint (ad esempio, il processo è bloccato, non risponde o è in corso un GC lungo), si jmapverificherà un timeout e non verrà eseguito correttamente .

Riassumiamo i vantaggi e gli svantaggi di Dynamic Attach.

Professionisti.

  • Il dump dell'heap e altre operazioni vengono eseguite in collaborazione da JVM alla massima velocità.
  • È possibile utilizzare qualsiasi versione di jmapo jstackper connettersi a qualsiasi altra versione di JVM.

Contro.

  • Lo strumento dovrebbe essere eseguito dallo stesso utente ( euid/ egid) della JVM di destinazione.
  • Può essere utilizzato solo su JVM live e in buona salute.
  • Non funzionerà se viene avviata la JVM di destinazione -XX:+DisableAttachMechanism.

jmap -F / jstack -F

Quando viene eseguito con -Fgli strumenti, passare alla modalità speciale che include HotSpot Serviceability Agent . In questa modalità il processo di destinazione è congelato; gli strumenti leggono la sua memoria tramite le funzionalità di debug del sistema operativo, ovvero ptracesu Linux.

  1. jmap -Finvoca PTRACE_ATTACHsulla JVM di destinazione. Il processo target viene sospeso incondizionatamente in risposta al SIGSTOPsegnale.

  2. Lo strumento legge la memoria JVM utilizzando PTRACE_PEEKDATA. ptracepuò leggere solo una parola alla volta, quindi sono necessarie troppe chiamate per leggere il grande mucchio del processo di destinazione. Questo è molto e molto lento.

  3. Lo strumento ricostruisce le strutture interne della JVM in base alla conoscenza della particolare versione della JVM. Poiché diverse versioni di JVM hanno un layout di memoria diverso, la -Fmodalità funziona solo se jmapproviene dallo stesso JDK del processo Java di destinazione.

  4. Lo strumento crea esso stesso il dump dell'heap e quindi riprende il processo di destinazione.

Professionisti.

  • Non è richiesta la collaborazione della JVM di destinazione. Può essere utilizzato anche su un processo sospeso.
  • ptracefunziona ogni volta che i privilegi a livello di sistema operativo sono sufficienti. Ad esempio, rootpuò eseguire il dump dei processi di tutti gli altri utenti.

Contro.

  • Molto lento per grandi cumuli.
  • Lo strumento e il processo di destinazione dovrebbero provenire dalla stessa versione di JDK.
  • Il safepoint non è garantito quando lo strumento si collega in modalità forzata. Sebbene jmapcerchi di gestire tutti i casi speciali, a volte può accadere che la JVM di destinazione non sia in uno stato coerente.

Nota

C'è un modo più veloce per eseguire i dump dell'heap in modalità forzata. Innanzitutto, crea un coredump con gcore, quindi esegui jmapil file core generato. Vedi la domanda correlata .


85

Ho appena scoperto che jmap (e presumibilmente jvisualvm quando lo si utilizza per generare un dump dell'heap) impone che l'utente che esegue jmap deve essere lo stesso utente che esegue il processo che tenta di essere scaricato.

nel mio caso la jvm per la quale voglio un dump dell'heap viene eseguita dall'utente linux "jboss". quindi, dove sudo jmap -dump:file.bin <pid>riportava "Impossibile aprire il socket:", sono stato in grado di prendere il mio dump dell'heap usando:

sudo -u jboss jmap -dump:file.bin <pid>

Penso che dovrebbe essere \ -dump: file.bin <pid> poiché è necessario sfuggire al - quando si passa il parametro da sudo a jmap.
adam

Questo è! È necessario eseguire sudo anche per jmap e jcmd.
xtian

wow .. Questo effettivamente ha funzionato. Questa dovrebbe essere la risposta accettata
Lalit Rao

3

Proprio come ha detto ben_wing , puoi correre con:

sudo -u jboss-as jmap -dump:file.bin <pid>

(nel mio caso l'utente è jboss-as, ma il tuo potrebbe essere jbosso qualcun altro.)

Ma non è stato sufficiente, perché mi ha chiesto una password ( [sudo] password for ec2-user:), sebbene potessi eseguire sudosenza chiedermi una password con altri comandi.

Ho trovato la soluzione qui e dovevo solo aggiungerne un'altra sudoprima:

sudo sudo -u jboss-as jmap -dump:file.bin <pid>

Funziona anche con altri comandi come jcmde jinfo.


Il doppio sudomi salva la giornata!
Sher10ck

[root@v5 ~]# sudo sudo -u es jmap -dump:file=tmp.bin 26283 si trasforma in errore sudo: jmap: command not found. Ho già configurato il percorso java in .bash_profile, cosa dovrei fare.
roamer

@roamer Forse è perché quando esegui come esutente, il .bash_profilenon viene applicato (perché il profilo bash è correlato al tuo utente, presumo). Io consiglio di includere il percorso java in modo più globale, o forse specificare il percorso nel comando java, come sudo sudo -u es PATH="$PATH:/java/path" jmap -dump:file=tmp.bin 26283(dove /java/pathè il percorso di Java, e fare in modo che esso ha jmapin esso ).
Lucas Basquerotto

Configuro il percorso java in /home/es/.bash_profile e posso usare jmap quando effettuo il login con es user. Questo cmd sudo sudo -u es /usr/java/jdk1.8.0_181-cloudera/bin/jmap -dump:file=tmp.bin 26283funziona. Molte grazie.
roamer

2

Se la tua applicazione è in esecuzione come servizio systemd, dovresti aprire il file di servizio sotto /usr/lib/systemd/system/e denominato dal nome del tuo servizio. Quindi controlla se l' attributo privateTmp è vero.

Se è vero, dovresti cambiarlo in falso, quindi aggiornare il servizio con il comando come segue: systemctl daemon-reload systemctl restart [servicename] Se vuoi eseguire jmap / jcmd prima del riavvio, puoi usare lo script execStop nel file di servizio. Basta inserire il comando in esso ed eseguiresystemctl stop [service name]


Prima di aggiornare /usr/lib/systemd/system/elasticsearch.service, impostando privateTmp su false, ho ricevuto questo errore: Impossibile aprire il file socket: il processo di destinazione non risponde o HotSpot VM non caricato, anche se stavo eseguendo jmap come l'utente
elasticsearch
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.