Jmap не может подключиться, чтобы сделать дамп - PullRequest
49 голосов
/ 26 мая 2010

У нас есть открытая бета-версия приложения, которая иногда вызывает переполнение пространства кучи. JVM реагирует, уезжая в постоянный отпуск.

Чтобы проанализировать это, я хотел бы заглянуть в память в тот момент, когда это не удалось. Ява не хочет, чтобы я это делал. Процесс все еще находится в памяти, но, похоже, он не распознается как процесс Java.

Рассматриваемый сервер - это сервер Debian Lenny, Java 6u14

/opt/jdk/bin# ./jmap -F -dump:format=b,file=/tmp/apidump.hprof 11175
Attaching to process ID 11175, please wait...
sun.jvm.hotspot.debugger.NoSuchSymbolException: Could not find symbol "gHotSpotVMTypeEntryTypeNameOffset" in any of the known library names (libjvm.so, libjvm_g.so, gamma_g)
at sun.jvm.hotspot.HotSpotTypeDataBase.lookupInProcess(HotSpotTypeDataBase.java:390)
at sun.jvm.hotspot.HotSpotTypeDataBase.getLongValueFromProcess(HotSpotTypeDataBase.java:371)
at sun.jvm.hotspot.HotSpotTypeDataBase.readVMTypes(HotSpotTypeDataBase.java:102)
at sun.jvm.hotspot.HotSpotTypeDataBase.<init>(HotSpotTypeDataBase.java:85)
at sun.jvm.hotspot.bugspot.BugSpotAgent.setupVM(BugSpotAgent.java:568)
at sun.jvm.hotspot.bugspot.BugSpotAgent.go(BugSpotAgent.java:494)
at sun.jvm.hotspot.bugspot.BugSpotAgent.attach(BugSpotAgent.java:332)
at sun.jvm.hotspot.tools.Tool.start(Tool.java:163)
at sun.jvm.hotspot.tools.HeapDumper.main(HeapDumper.java:77)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at sun.tools.jmap.JMap.runTool(JMap.java:179)
at sun.tools.jmap.JMap.main(JMap.java:110)
Debugger attached successfully.
sun.jvm.hotspot.tools.HeapDumper requires a java VM process/core!

Ответы [ 14 ]

83 голосов
/ 31 мая 2010

Решение было очень простым. Я запускал jmap от имени root, но мне пришлось запускать его как пользователь, запустивший jvm. Теперь я пойду спрятать голову от стыда.

30 голосов
/ 24 сентября 2015

Я запускал jmap и приложение с одним и тем же пользователем и все еще получаю ошибку.

Решение было запущено этой командой до jmap

echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope

Чем просто использовать jmap и будет нормально работать

jmap -heap 17210
15 голосов
/ 24 декабря 2014

Будущие Googlers:

Это также может произойти, если вы установили JDK во время процесса, который вы пытаетесь запустить в jmap.

Если это так, перезапустите процесс Java.

11 голосов
/ 05 апреля 2016

Если кто-то пытается получить дамп кучи Java-приложения в контейнере Docker. Это единственное решение, которое сработало для меня:

docker exec <container-name> jcmd 1 GC.heap_dump /tmp/docker.hprof

Он в основном сбрасывает кучу процесса с pid = 1 , используя jcmd

См. https://docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/tooldescr006.html

6 голосов
/ 26 мая 2010

Что произойдет, если вы просто запустите

./jmap -heap 11175 

А вы уверены, что JVM приложения идентична JVM JMAP? (та же версия и т. д.)

5 голосов
/ 17 ноября 2017

Выполните следующие шаги, чтобы извлечь поток и дамп кучи из контейнера докера

  1. Запустите приведенную ниже команду, чтобы ударить в контейнер. Пожалуйста, измените CONTAINER_NAME соответствующим образом
   docker exec -it CONTAINER_NAME bash
  1. Затем введите jps, чтобы найти все детали приложения Java и извлечь PID для вашего приложения
jps
  1. Затем выполните приведенную ниже команду, чтобы получить дамп потока. Пожалуйста, измените PID соответствующим образом

    jstack PID > threadDump.tdump 
    
  2. Затем выполните приведенную ниже команду, чтобы получить дамп кучи. Пожалуйста, измените PID соответствующим образом

    jmap -dump:live,format=b,file=heapDump.hprof PID 
  1. Затем выйдите из docker-контейнера и загрузите threadDump.tdump и heapDump.hprof из docker-контейнера, выполнив следующую команду. Пожалуйста, измените CONTAINER_NAME соответствующим образом
 sudo docker cp CONTAINER_NAME:threadDump.tdump .
 sudo docker cp CONTAINER_NAME:heapDump.hprof .
3 голосов
/ 01 июня 2016

Вам необходимо использовать jmap, поставляемый с JVM.

2 голосов
/ 20 декабря 2017
1.Execute "Docker ps", will give the container Id of all services and collect the container id foe TSC.
2.Execute "docker exec -it CONTAINER_ID bash" (replace CONTAINER_ID with TSC Container id)
3.Bash will come and then execute the "jps" on bash, that will give you the PID for process(it will be 1 for jar)
4.Execute the "jstack PID > threadDump.tdump"(replace PID with process id received in step 3, it should be 1)
5.Execute the "jmap -dump:format=b,file=heapDump.hprof PID"(replace PID with process id received in step 3, it should be 1)
6.Then we have to exit the bash using "exit" command
7.Execute "sudo docker cp CONTAINER_ID:heapDump.hprof ." from ec2 command line, that will copy the dump file on ec2 machine present working directory.
8.Execute "sudo docker cp CONTAINER_ID:threadDump.tdump ." from ec2 command line, that will copy the dump file on ec2 machine present working directory.
2 голосов
/ 17 августа 2017

У меня та же проблема, я пытаюсь найти утечку памяти в процессе, выполняющемся внутри контейнера Docker. Я не смог использовать jmap, вместо этого я использовал это:

jcmd <pid> GC.class_histogram 

Это дает вам список объектов в памяти. А из документации Oracle:

Рекомендуется использовать последнюю утилиту, jcmd вместо утилиты jmap, для расширенной диагностики и снижения производительности. https://docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/memleaks004.html

2 голосов
/ 19 августа 2016

Для меня сработало просто выполнить команду с sudo, как в:

sudo jmap -heap 21797
...