我们有一个应用程序的公开测试版,偶尔会导致堆空间溢出.JVM通过永久度假来做出反应.
为了分析这一点,我想在失败的时候窥视记忆.Java不希望我这样做.该过程仍在内存中,但它似乎不被认为是一个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.(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!
Jasper Floor.. 85
解决方案非常简单.我以root身份运行jmap,但是我必须以启动jvm的用户身份运行它.我现在会羞愧地隐藏自己的头脑.
解决方案非常简单.我以root身份运行jmap,但是我必须以启动jvm的用户身份运行它.我现在会羞愧地隐藏自己的头脑.
我正在运行jmap和具有相同用户的应用程序,但仍然得到错误.
解决方案是在jmap之前执行的
echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope
比只使用jmap并且可以正常工作
jmap -heap 17210
未来的Google员工:
如果您在尝试jmap的进程正在运行时安装了JDK ,也会发生这种情况.
如果是这种情况,请重新启动java进程.
如果有人试图在Docker容器中获取Heap Dump of Java应用程序.这是唯一对我有用的解决方案:
docker execjcmd 1 GC.heap_dump /tmp/docker.hprof
它基本上使用jcmd转储pid = 1的进程堆
请参阅https://docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/tooldescr006.html
如果你跑的话会发生什么
./jmap -heap 11175
您确定应用程序JVM与JMAP JVM完全相同吗?(同版本等)
请按照以下步骤从Docker容器中获取线程和堆转储
运行以下命令将其扑向容器中。请适当更改CONTAINER_NAME
docker exec -it CONTAINER_NAME bash
然后键入jps以查找所有Java应用程序详细信息,并为您的应用程序提取PID
jps
然后运行以下命令以获取线程转储。请适当更改PID
jstack PID > threadDump.tdump
然后运行以下命令以获取堆转储。请适当更改PID
jmap -dump:live,format=b,file=heapDump.hprof PID
然后从Docker容器退出并通过运行以下命令从Docker容器下载threadDump.tdump和heapDump.hprof。请适当更改CONTAINER_NAME
sudo docker cp CONTAINER_NAME:threadDump.tdump . sudo docker cp CONTAINER_NAME:heapDump.hprof .