Ejecutando jmap obteniendo No se puede abrir el archivo de socket

85

Tuve que ejecutar jmappara realizar un volcado de mi proceso. pero jvmregresó:

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

Entonces usé el -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. ¿ -F Está bien usar para realizar un volcado de pila?
  2. Estoy esperando 20 minutos y aún no he terminado. ¿Alguna idea de por qué?
Rayman
fuente

Respuestas:

181

jmapvs. jmap -F, así como jstackvs. jstack -Futilizar mecanismos completamente diferentes para comunicarse con la JVM de destino.

jmap / jstack

Cuando se ejecuta sin -Festas herramientas, utilice Dynamic Attach Mechanism . Esto funciona de la siguiente manera.

  1. Antes de conectarse al proceso 1234 de Java, jmapcrea un archivo .attach_pid1234en el directorio de trabajo del proceso de destino o en /tmp.

  2. Luego jmapenvía SIGQUITal proceso de destino. Cuando JVM detecta la señal y la encuentra .attach_pid1234, inicia el AttachListenerhilo.

  3. AttachListenerthread crea un socket de dominio UNIX /tmp/.java_pid1234para escuchar comandos de herramientas externas.

  4. Por razones de seguridad cuando una conexión (de jmapse acepta), verifica JVM que las credenciales de los pares socket son iguales a euidy egidde proceso JVM. Es por eso jmapque no funcionará si lo ejecuta un usuario diferente (incluso por root).

  5. jmapse conecta al enchufe y envía el dumpheapcomando.

  6. Este comando es leído y ejecutado por el AttachListenerhilo de la JVM. Toda la salida se envía de vuelta al enchufe. Dado que el volcado de pila se realiza en proceso directamente por JVM, la operación es realmente rápida. Sin embargo, JVM solo puede hacer esto en puntos seguros . Si no se puede alcanzar un punto seguro (por ejemplo, el proceso se bloquea, no responde o hay un GC largo en curso), jmapse agotará el tiempo de espera y fallará.

Resumamos los beneficios y los inconvenientes de Dynamic Attach.

Pros.

  • El volcado de pila y otras operaciones se ejecutan en colaboración con JVM a la máxima velocidad.
  • Puede utilizar cualquier versión de jmapo jstackpara conectarse a cualquier otra versión de JVM.

Contras.

  • La herramienta debe ejecutarla el mismo usuario ( euid/ egid) que la JVM de destino.
  • Solo se puede usar en JVM en vivo y en buen estado.
  • No funcionará si se inicia la JVM de destino -XX:+DisableAttachMechanism.

jmap -F / jstack -F

Cuando se ejecuta con -Flas herramientas, cambie al modo especial que cuenta con HotSpot Serviceability Agent . En este modo, el proceso de destino se congela; las herramientas leen su memoria a través de las instalaciones de depuración del sistema operativo, es decir, ptraceen Linux.

  1. jmap -Finvoca PTRACE_ATTACHen la JVM de destino. El proceso objetivo se suspende incondicionalmente en respuesta a la SIGSTOPseñal.

  2. La herramienta lee la memoria JVM usando PTRACE_PEEKDATA. ptracepuede leer solo una palabra a la vez, por lo que se requieren demasiadas llamadas para leer el gran montón del proceso de destino. Esto es muy y muy lento.

  3. La herramienta reconstruye las estructuras internas de la JVM basándose en el conocimiento de la versión particular de la JVM. Dado que las diferentes versiones de JVM tienen un diseño de memoria diferente, el -Fmodo solo funciona si jmapproviene del mismo JDK que el proceso Java de destino.

  4. La herramienta crea un volcado de montón y luego reanuda el proceso de destino.

Pros.

  • No se requiere cooperación de la JVM de destino. Puede usarse incluso en un proceso colgado.
  • ptracefunciona siempre que los privilegios de nivel de sistema operativo son suficientes. Por ejemplo, rootpuede volcar procesos de todos los demás usuarios.

Contras.

  • Muy lento para grandes montones.
  • La herramienta y el proceso de destino deben ser de la misma versión de JDK.
  • El punto seguro no está garantizado cuando la herramienta se conecta en modo forzado. Aunque jmapintenta manejar todos los casos especiales, a veces puede suceder que la JVM de destino no esté en un estado consistente.

Nota

Existe una forma más rápida de realizar volcados de pila en modo forzado. Primero, cree un volcado de memoria con gcorey luego ejecute jmapel archivo central generado. Vea la pregunta relacionada .

apangin
fuente
84

Acabo de descubrir que jmap (y presumiblemente jvisualvm cuando se usa para generar un volcado de pila) impone que el usuario que ejecuta jmap debe ser el mismo usuario que ejecuta el proceso que intenta ser volcado.

en mi caso, el usuario de linux "jboss" está ejecutando el jvm para el que quiero un volcado de pila. Entonces, ¿dónde sudo jmap -dump:file.bin <pid>estaba el informe "No se puede abrir el socket:", pude tomar mi volcado de pila usando:

sudo -u jboss jmap -dump:file.bin <pid>
ben_wing
fuente
Creo que debería ser \ -dump: file.bin <pid> ya que necesita escapar del - al pasar el parámetro de sudo a jmap.
Adam
¡Eso es todo! Necesita sudo para jmap y jcmd también.
xtian
wow .. Esto realmente funcionó. Esta debería ser la respuesta aceptada
Lalit Rao
3

Al igual que ben_wing dicho, puede ejecutar con:

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

(en mi caso el usuario es jboss-as, pero el tuyo podría serlo jbosso algún otro).

Pero no fue suficiente, porque me pidió una contraseña ( [sudo] password for ec2-user:), aunque pude ejecutar sudosin pedirme una contraseña con otros comandos.

Encontré la solución aquí , y solo necesitaba agregar otra sudoprimero:

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

Funciona con otros comandos como jcmdy jinfotambién.

Lucas Basquerotto
fuente
¡El doble sudome salva el día!
Sher10ck
[root@v5 ~]# sudo sudo -u es jmap -dump:file=tmp.bin 26283 se convierte en error sudo: jmap: command not found. Ya configuré la ruta de Java en .bash_profile, ¿qué debo hacer?
itinerante
@roamer Tal vez sea porque cuando ejecuta como esusuario, .bash_profileno se está aplicando (porque el perfil de bash está relacionado con su usuario, supongo). Aconsejo a incluir la ruta de Java de una manera más global, o tal vez especificar la ruta de Java en el comando, como sudo sudo -u es PATH="$PATH:/java/path" jmap -dump:file=tmp.bin 26283(donde /java/pathes la ruta de Java, y asegurarse de que se dispone jmapen ella ).
Lucas Basquerotto
Configuré la ruta de java en /home/es/.bash_profile, y puedo usar jmap cuando inicie sesión con el usuario es. Este cmd sudo sudo -u es /usr/java/jdk1.8.0_181-cloudera/bin/jmap -dump:file=tmp.bin 26283funciona. Muchas gracias.
itinerante
2

Si su aplicación se ejecuta como un servicio systemd, debe abrir el archivo de servicio que se encuentra debajo /usr/lib/systemd/system/y con el nombre de su servicio. Luego, verifique si el atributo privateTmp es verdadero.

Si es verdadero, debe cambiarlo a falso, luego actualice el servicio con el comando de la siguiente manera: systemctl daemon-reload systemctl restart [servicename] Si desea ejecutar jmap / jcmd antes de reiniciar, puede usar el script execStop en el archivo de servicio. Solo ingrese el comando y ejecutesystemctl stop [service name]

Sencillo
fuente
Antes de actualizar /usr/lib/systemd/system/elasticsearch.service, estableciendo privateTmp en falso, recibí este error: No se puede abrir el archivo de socket: el proceso de destino no responde o HotSpot VM no está cargada, aunque estaba ejecutando jmap como el usuario de
elasticsearch