介绍


排查内存溢出时,执行jmap命令报:

pid:Unable to open socket file: target process not responding or HotSport VM not loaded
The -F option can be used when the target process is not responding.

解决办法1 根据提示加-F

根据提示加-F,结果如下

Dumping heap to dump.bin …
Exception in thread”main” java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at sun.tools.jmap.JMap.runTool(JMap.java:201)
at sun.tools.jmap.JMap.main(JMap.java:130)
Caused by: java.lang.InternalError: Metadata does not appear to be polymorphic
at sun.jvm.hotspot.types.basic.BasicTypeDataBase.findDynamicTypeForAddress(BasicTypeDataBase.java:278)
at sun.jvm.hotspot.runtime.VirtualBaseConstructor.instantiateWrapperFor(VirtualBaseConstructor.java:102)
at sun.jvm.hotspot.oops.Metadata.instantiateWrapperFor(Metadata.java:68)
at sun.jvm.hotspot.memory.DictionaryEntry.klass(DictionaryEntry.java:71)
at sun.jvm.hotspot.memory.Dictionary.classesDo(Dictionary.java:66)
at sun.jvm.hotspot.memory.SystemDictionary.classesDo(SystemDictionary.java:190)
at sun.jvm.hotspot.memory.SystemDictionary.allClassesDo(SystemDictionary.java:183)
at sun.jvm.hotspot.utilities.HeapHprofBinWriter.writeClasses(HeapHprofBinWriter.java:942)
at sun.jvm.hotspot.utilities.HeapHprofBinWriter.write(HeapHprofBinWriter.java:427)
at sun.jvm.hotspot.tools.HeapDumper.run(HeapDumper.java:62)
at sun.jvm.hotspot.tools.Tool.startInternal(Tool.java:260)
at sun.jvm.hotspot.tools.Tool.start(Tool.java:223)
at sun.jvm.hotspot.tools.Tool.execute(Tool.java:118)
at sun.jvm.hotspot.tools.HeapDumper.main(HeapDumper.java:83)
… 6 more

解决办法2 切换到进程用户 & cd 到进程用户文件夹下

其实大部分情况是用户错误,切换到进程所在用户

使用 top,或 ps命令查看 进程用户

top - 16:16:49 up 152 days, 1:30, 3 users, load average: 0.00, 0.01, 0.13
Tasks: 121 total, 1 running, 120 sleeping, 0 stopped, 0 zombie
%Cpu(s): 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 16412472 total, 12663144 free, 1150820 used, 2598508 buff/cache
KiB Swap: 4063228 total, 4063228 free, 0 used. 14822356 avail Mem

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
30009 test 20 0 7892124 870748 14036 S 0.3 5.3 0:53.15 java -jar hdms-assembly.jar -Xms128m -Xmx512m
510 root 20 0 63648 25424 25116 S 0.0 0.2 0:45.15 /usr/lib/systemd/systemd-journald
1256 root 20 0 341396 16056 14220 S 0.0 0.1 9:51.36 /usr/sbin/rsyslogd -n
690 polkitd 20 0 612936 12024 4940 S 0.0 0.1 0:45.10 /usr/lib/polkit-1/polkitd –no-debug
827 root 20 0 476976 8872 6884 S 0.0 0.1 64:20.49 /usr/sbin/NetworkManager –no-daemon
943 root 20 0 198388 8612 5440 S 0.0 0.1 151:46.98 /usr/sbin/vmtoolsd
29917 root 20 0 116184 2800 1808 S 0.0 0.0 10:13.82 -bash
720 root 20 0 103344 2736 2032 S 0.0 0.0 0:00.03 login – root

切换到进程对应的用户: su test

jmap -dump:file=30009.bin 300009

然后执行命令

解决办法3 内存快照


当发生内存溢出或者将要发生内存溢出的时候,我们首先需要去获取Heap Dump,在发生内存的时间点人工去获取Heap Dump是不现实的,因为我们不知道什么时候会发生内存溢出,但是在JVM启动的时候通过命令行给JVM传递如下的参数就可以在发生内存溢出的时候,自动生成Heap Dump

在启动服务的时候加上JVM参数-XXHeapDumpOnOutOfMemoryError
Tomcat

JAVA_OPTS=”-server -Xms512m -Xmx512m -Xss1024K -XX:PermSize=128m -XX:MaxPermSize=256m -XXHeapDumpOnOutOfMemoryError”

在下次项目发生OOM时,自动生成内存快照