Java Jmap 无法连接进行转储
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2913948/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Jmap can't connect to make a dump
提问by Jasper Floor
We have an open beta of an app which occasionally causes the heapspace to overflow. The JVM reacts by going on a permanent vacation.
我们有一个应用程序的公开测试版,它偶尔会导致堆空间溢出。JVM 的反应是永久休假。
To analyze this I would like to peek into the memory at the point where it failed. Java does not want me to do this. The process is still in memory but it doesn't seem to be recognized as a java process.
为了分析这一点,我想在它失败的地方查看内存。Java 不希望我这样做。该进程仍在内存中,但它似乎没有被识别为 java 进程。
The server in question is a debian Lenny server, Java 6u14
有问题的服务器是 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!
采纳答案by Jasper Floor
The solution was very simple. I was running the jmap as root, but I had to run it as the user who started the jvm. I will now go hide my head in shame.
解决方案非常简单。我以 root 身份运行 jmap,但我必须以启动 jvm 的用户身份运行它。我现在要羞愧地把头藏起来。
回答by bwawok
What happens if you just run
如果你只是跑会发生什么
./jmap -heap 11175
And are you sure the application JVM is identical to the JMAP JVM? (same version, etc)
您确定应用程序 JVM 与 JMAP JVM 相同吗?(相同版本等)
回答by OkieOth
I got the same jmap error on a linux machine that have two different OpenJdks installed. First I installed OpenJDK 1.6 and after that OpenJDK 1.7.
我在安装了两个不同 OpenJdks 的 linux 机器上遇到了相同的 jmap 错误。首先我安装了 OpenJDK 1.6,然后是 OpenJDK 1.7。
A call of ...
一个...
/usr/lib/jvm/java-1.7.0-openjdk-amd64/bin/java -XshowSettings:properties -version
# produce the following output ...
...
java.library.path = /usr/java/packages/lib/amd64
/usr/lib/x86_64-linux-gnu/jni
/lib/x86_64-linux-gnu
/usr/lib/x86_64-linux-gnu
/usr/lib/jni
/lib
/usr/lib
...
java version "1.7.0_65"
With including '/usr/lib' every with OpenJDK 1.7.* started program includes the libraries of the first installed JDK (in my case OpenJDK 1.6.*). So the jmap versions of Java6 and Java7 failed.
包含“/usr/lib”后,每个 OpenJDK 1.7.* 启动程序都包含第一个安装的 JDK(在我的情况下为 OpenJDK 1.6.*)的库。所以Java6和Java7的jmap版本都失败了。
After I changed the start for the Java7 programms with included OpenJDK 1.7 libraries ...
在我使用包含的 OpenJDK 1.7 库更改了 Java7 程序的启动之后......
/usr/lib/jvm/java-1.7.0-openjdk-amd64/bin/java -Djava.library.path=/usr/lib/jvm/java- \
7-openjdk-amd64/jre/lib/amd64/server:/usr/java/packages/lib/amd64: \
/usr/lib/x86_64-linux-gnu/jni:/lib/x86_64-linux-gnu:/usr/lib/ \
x86_64-linux-gnu:/usr/lib/jni:/lib:/usr/lib ...
I was able access proccess with the Java 7 version of the jmap program. But it needs a sudo to run.
我能够使用 jmap 程序的 Java 7 版本访问进程。但它需要一个 sudo 才能运行。
回答by Ariel T
Future Googlers:
未来的谷歌员工:
This could also happen if you installed the JDK whilethe process you're trying to jmap was running.
如果您在尝试 jmap 的进程正在运行时安装了 JDK ,也可能会发生这种情况。
If that's the case, restart the java process.
如果是这种情况,请重新启动 java 进程。
回答by jpozorio
I was running the jmap and the application with the same user and still get the error.
我正在使用同一用户运行 jmap 和应用程序,但仍然出现错误。
The solution was run that comand before the jmap
解决方案是在 jmap 之前运行该命令
echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope
Than is just use jmap and will works fine
不仅仅是使用 jmap 并且可以正常工作
jmap -heap 17210
回答by kisna
When none of these work or if you don't want to change sensitive OS flags such as ptrace_scope:
当这些都不起作用或者您不想更改敏感的操作系统标志(例如 ptrace_scope)时:
Either you can use jconsole/jvisualvm to trigger heap dumpsor run any JMX client directly from console as follows as you are doing it locally on the machine that needs the dump and so is faster:
您可以使用 jconsole/jvisualvm触发堆转储或直接从控制台运行任何 JMX 客户端,如下所示,因为您在需要转储的机器上本地执行此操作,因此速度更快:
echo 'jmx_invoke -m com.sun.management:type=HotSpotDiagnostic dumpHeap heapdump-20160309.hprof false' | java -jar jmxsh.jar -h $LOCALHOST_OR_IP -p $JMX_PORT
I used the wget https://github.com/davr/jmxsh/raw/master/jmxsh.jarfor this example.
我在这个例子中使用了 wget https://github.com/davr/jmxsh/raw/master/jmxsh.jar。
回答by Oleksandr
If someone tries to get Heap Dump of Java application in Docker container. This is the only solution that worked for me:
如果有人试图在 Docker 容器中获取 Java 应用程序的堆转储。这是唯一对我有用的解决方案:
docker exec <container-name> jcmd 1 GC.heap_dump /tmp/docker.hprof
It basically dumps the heap of process with pid=1using jcmd
它基本上使用jcmd转储pid=1的进程堆
See https://docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/tooldescr006.html
请参阅https://docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/tooldescr006.html
回答by ejaenv
You need to use the jmap that comes with the JVM.
需要使用JVM自带的jmap。
回答by CommonCoreTawan
What worked for me was to simply issue the command with sudo as in:
对我有用的是简单地使用 sudo 发出命令,如下所示:
sudo jmap -heap 21797
回答by Javier Lopez
I have the same problem, I'm trying to find a memory leak in a process running inside a Docker container. I wasn't able to use jmap, instead I used this:
我有同样的问题,我试图在 Docker 容器内运行的进程中找到内存泄漏。我无法使用 jmap,而是使用了这个:
jcmd <pid> GC.class_histogram
This gives you a list of the objects in the memory. And from the Oracle documentation:
这为您提供了内存中的对象列表。从 Oracle 文档中:
It is recommended to use the latest utility, jcmd instead of jmap utility for enhanced diagnostics and reduced performance overhead. https://docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/memleaks004.html
建议使用最新的实用程序 jcmd 而不是 jmap 实用程序以增强诊断并降低性能开销。https://docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/memleaks004.html