jps не отображает процесс tomcat, а jmap не может создать дамп кучи

У меня есть работающий сервер tomcat (9.0.39.0), запущенный пользователем cpappt и работающий с pid: 1682650. Машина, на которой работает этот сервер, не является голым железом, а VMware машина, а JVM от OpenJ9

> ps -ef | grep Bootstrap
cpappt   1682650       1  0 Jan01 ?        01:09:58 /srv/jdk11/bin/java
  -Djava.util.logging.config.file=/srv/test/cpappt/tomcat/conf/logging.properties
  -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -server 
  -Xms32m -Xmx2048m -XX:+HeapDumpOnOutOfMemoryError
  -Dcrewportalenvironment=test
  -Denvironment=test
  -Doracle.net.tns_admin=/CONFIG/global/ORA/HA
  -Dspring.profiles.active=test,notification-services-intern
  -Djdk.tls.ephemeralDHKeySize=2048
  -Djava.protocol.handler.pkgs=org.apache.catalina.webresources
  -Dorg.apache.catalina.security.SecurityListener.UMASK=0022
  -Djava.awt.headless=true
  -Dcom.sun.management.jmxremote
  -Dfile.encoding=UTF-8
  -Dsun.jnu.encoding=UTF-8
  -Dcom.sun.management.jmxremote.port=7305
  -Dcom.sun.management.jmxremote.ssl=false
  -Dcom.sun.management.jmxremote.password.file=conf/jmxremote.password
  -Dignore.endorsed.dirs= -classpath /srv/test/cpappt/tomcat/bin/bootstrap.jar:/srv/test/cpappt/tomcat/bin/tomcat-juli.jar
  -Dcatalina.base=/srv/test/cpappt/tomcat
  -Dcatalina.home=/srv/test/cpappt/tomcat
  -Djava.io.tmpdir=/srv/test/cpappt/tomcat/temp org.apache.catalina.startup.Bootstrap start

Я хочу извлечь heap dump кота, чтобы проанализировать потенциальную утечку памяти.

Я пытался использовать jps для получения pid сервера tomcat, к сожалению, я вижу только pid самого jps.

> jps -l
952152 jdk.jcmd/openj9.tools.attach.diagnostics.tools.Jps

и я также запускаю команду jps от имени того же пользователя, который запустил сервер tomcat

> whoami 
cpappt

Я также пробовал запустить команду jps, добавив java.io.tmpdir, указанный в сценарии запуска tomcat, что приводит к тому же результату, что и раньше (примечание: само tmpdir пусто).

jps -l -J-Djava.io.tmpdir=/srv/test/cpappt/tomcat/temp

(Дополнительное замечание: если я запустил небольшую программу Foo, jps показывает мне pid этой программы.)

Затем я попытался создать дамп кучи с помощью команды pid из команды ps, которая не удалась:

> jmap -dump:live,format=b,file=/tmp/dump.hprof 1682650
unrecognized option -dump:live,format=b,file=/tmp/dump.hprof
jmap: obtain heap information about a Java process
 Usage:
    jmap <option>* <vmid>
        <vmid>: Attach API VM ID as shown in jps or other Attach API-based tools
        <vmid>s are read from stdin if none are supplied as arguments
    -histo: print statistics about classes on the heap, including number of objects and aggregate size
    -histo:live : Print only live objects
    -J: supply arguments to the Java VM running jmap
NOTE: this utility might significantly affect the performance of the target VM.
At least one option must be selected.

Если я просто попытаюсь увидеть гистограмму, это также не удастся:

> jmap -histo:live 1682650
Error getting data from 1682650: Exception connecting to 1682650

Также jcmd не может создать дамп:

> jcmd 1682650 GC.heap_dump /tmp/heapdump
Error getting data from 1682650: Exception connecting to 1682650
...

Я почему-то подозреваю, что обе проблемы (jps и jmap) связаны... Итак, если у кого-нибудь есть идея, в чем может быть проблема или даже как я могу создать дамп кучи, это было бы здорово.

Дополнительная информация с сервера tomcat (и java):

Server version number: 9.0.39.0
OS Name:               Linux
OS Version:            5.7.0-0.bpo.2-amd64
Architektur:           amd64
Java Home:             /srv/jdk-11.0.8+10_openj9
JVM Version:           11.0.8+10
JVM Hersteller:        Eclipse OpenJ9

> java -version
openjdk version "11.0.8" 2020-07-14
OpenJDK Runtime Environment AdoptOpenJDK (build 11.0.8+10)
Eclipse OpenJ9 VM AdoptOpenJDK (build openj9-0.21.0, JRE 11 Linux amd64-64-Bit Compressed References 20200715_697 (JIT enabled, AOT enabled)
OpenJ9   - 34cf4c075
OMR      - 113e54219
JCL      - 95bb504fbb based on jdk-11.0.8+10)

> which java
/srv/jdk11/bin/java

> which jps
/srv/jdk11/bin/java

> which jmap 
/srv/jdk11/bin/jmap

Обновление: 09 января 2021 г.

Наконец-то я смог связаться с коллегой, который знает пароль для пользователя jmx, поэтому, используя jconsole, я смог вызвать heap dump, но смог вызвать только triggerClassicHeapDump(). Я скопировал файл на свой локальный компьютер и хотел проанализировать его с помощью Eclipse MemoryAnalyzer (я также добавил Diagnostic Tool Framework for Java (DTFJ)).

Но когда я пытаюсь открыть файл, я получаю сообщение об ошибке...

Error opening heap dump 'heapdump.20210119.100934.2621412.0001.txt'. Check the error log for further details.
Error opening heap dump 'heapdump.20210119.100934.2621412.0001.txt'. Check the error log for further details.
Error opening heap dump 'heapdump.20210119.100934.2621412.0001.txt'
Unable to read dump .../heapdump.20210119.100934.2621412.0001.phd metafile .../heapdump.20210119.100934.2621412.0001.txt in DTFJ format DTFJ-PHD (java.io.IOException)
Unable to read dump .../heapdump.20210119.100934.2621412.0001.phd metafile .../heapdump.20210119.100934.2621412.0001.txt in DTFJ format DTFJ-PHD
Error parsing Javacore (java.io.IOException)
Error parsing Javacore
com.ibm.dtfj.javacore.parser.framework.scanner.ScannerException: Maximum line length (32768) exceeded. Input file corrupt or not a javacore. (com.ibm.dtfj.javacore.parser.framework.parser.ParserException)
com.ibm.dtfj.javacore.parser.framework.scanner.ScannerException: Maximum line length (32768) exceeded. Input file corrupt or not a javacore.
Maximum line length (32768) exceeded. Input file corrupt or not a javacore. (com.ibm.dtfj.javacore.parser.framework.scanner.ScannerException)
Maximum line length (32768) exceeded. Input file corrupt or not a javacore.
Unable to read dump .../heapdump.20210119.100934.2621412.0001.txt metafile null in DTFJ format DTFJ-Javacore (java.io.IOException)
Unable to read dump .../heapdump.20210119.100934.2621412.0001.txt metafile null in DTFJ format DTFJ-Javacore
Error parsing Javacore (java.io.IOException)
Error parsing Javacore
com.ibm.dtfj.javacore.parser.framework.scanner.ScannerException: Maximum line length (32768) exceeded. Input file corrupt or not a javacore. (com.ibm.dtfj.javacore.parser.framework.parser.ParserException)
com.ibm.dtfj.javacore.parser.framework.scanner.ScannerException: Maximum line length (32768) exceeded. Input file corrupt or not a javacore.
Maximum line length (32768) exceeded. Input file corrupt or not a javacore. (com.ibm.dtfj.javacore.parser.framework.scanner.ScannerException)
Maximum line length (32768) exceeded. Input file corrupt or not a javacore.

person morecore    schedule 15.01.2021    source источник


Ответы (2)


Я добавил -Xdump:heap:events=user (см. Xdump Option Builder) в сценарий запуска кот и перезапустил сервер.

> ps -ef | grep Bootstrap
cpappt   1919301       1 99 14:38 pts/0    00:01:00 /srv/jdk11/bin/java 
 -Xms32m -Xmx2048m -XX:+HeapDumpOnOutOfMemoryError
 -Xdump:heap:events=user
 ...

Теперь я могу создать дамп кучи с помощью kill -3 <pid> (посмотрите на superuser: what-does-kill- 3-среднее). В каталоге catalina.base были созданы два файла:

  • javacore.<XXX>.txt (исходный дамп потока (-3 := SIGQUIT)) и
  • heapdump.<YYY>.phd (ну собственно дамп кучи)

Наконец я смог открыть файл heapdump.<YYY>.phd с помощью Eclipse MAT

Дополнительное примечание: мы обновили версию openj9 до текущей версии (23.0).

> java -version 
openjdk version "11.0.9" 2020-10-20
OpenJDK Runtime Environment AdoptOpenJDK (build 11.0.9+11)
Eclipse OpenJ9 VM AdoptOpenJDK (build openj9-0.23.0, JRE 11 Linux amd64-64-Bit Compressed References 20201022_810 (JIT enabled, AOT enabled)

Теперь jps также находит сервер tomcat

> jps -l
1919301 org.apache.catalina.startup.Bootstrap
1921897 jdk.jcmd/openj9.tools.attach.diagnostics.tools.Jps

Также jcmd работает:

> jcmd 1919301 Dump.heap dump
Dump written to .../tomcat/dump
person morecore    schedule 19.01.2021

Также рассмотрите возможность использования -Xdump:system:events=user, так как сгенерированный основной файл содержит гораздо больше информации, однако есть проблемы с чтением основных файлов IBM DTFJ, сгенерированных OpenJ9.

Анализатор памяти также может генерировать дампы кучи — см. Файл › Получить дамп кучи, но для «Присоединить API» и «Присоединить API с помощью вспомогательной JVM» может потребоваться некоторая настройка. Memory Analyzer 1.12 имеет некоторые улучшения в сборе дампов кучи, поэтому попробуйте последнюю версию.

person user13762112    schedule 23.06.2021