java内存文件jump和线程堆栈输出

概述

某天系统响应变慢需要分析原因,也许我们马上会想起java core分析三板斧,top、pid等等定位到线程使用jstack命令输出线程堆栈。那么如果是内存回收不掉的情况呢?也许你的系统已配置-XX HeapDumOnMemoryError,

-XX HeapDumpPath=XXX,但是一旦如果你没设置而且系统并没内存溢出,只是响应慢,回收不理想呢?这时候用什么命令呢?当然这个可以现查现用,但如果是在面试呢?也许你知道但是不记得了,但这个简单问题很可能直接会让面试官认为你没做过或者不知道,所以简单整理一下。

总结

一、jmap命令解析与使用

jmap -heap [pid] 查询内存使用情况

[root@fengniaoweb ~]# jmap -heap 2865
Attaching to process ID 2865, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.211-b12
​
using thread-local object allocation.
Parallel GC with 4 thread(s)
​
Heap Configuration:
 MinHeapFreeRatio         = 0
 MaxHeapFreeRatio         = 100
 MaxHeapSize              = 268435456 (256.0MB)
 NewSize                  = 42991616 (41.0MB)
 MaxNewSize               = 89128960 (85.0MB)
 OldSize                  = 87031808 (83.0MB)
 NewRatio                 = 2
 SurvivorRatio            = 8
 MetaspaceSize            = 21807104 (20.796875MB)
 CompressedClassSpaceSize = 1073741824 (1024.0MB)
 MaxMetaspaceSize         = 17592186044415 MB
 G1HeapRegionSize         = 0 (0.0MB)
​
Heap Usage:
PS Young Generation
Eden Space:
 capacity = 88080384 (84.0MB)
 used     = 86317448 (82.31873321533203MB)
 free     = 1762936 (1.6812667846679688MB)
 97.99849192301433% used
From Space:
 capacity = 524288 (0.5MB)
 used     = 32768 (0.03125MB)
 free     = 491520 (0.46875MB)
 6.25% used
To Space:
 capacity = 524288 (0.5MB)
 used     = 0 (0.0MB)
 free     = 524288 (0.5MB)
 0.0% used
PS Old Generation
 capacity = 179306496 (171.0MB)
 used     = 74843440 (71.37626647949219MB)
 free     = 104463056 (99.62373352050781MB)
 41.74050671315332% used
​
26363 interned Strings occupying 3142776 bytes.

要注意的是在使用CMS GC 情况下,jmap -heap的执行有可能会导致JAVA 进程挂起

jmap -histo [pid] 查看JVM堆中对象详细占用情况

// 限于篇幅仅粘贴示例
3007:             1             16  [Lorg.aspectj.weaver.ast.Var;
3008:             1             16  [Lorg.aspectj.weaver.patterns.AnnotationTypePattern;
3009:             1             16  [Lorg.aspectj.weaver.patterns.BindingPattern;
3010:             1             16  [Lorg.aspectj.weaver.tools.PointcutParameter;
3011:             1             16  [Lorg.springframework.web.context.request.async.CallableProcessingInterceptor;
3012:             1             16  [Lorg.springframework.web.context.request.async.DeferredResultProcessingInterceptor;
3013:             1             16  [Lsun.reflect.annotation.TypeAnnotation$LocationInfo$Location;
3014:             1             16  [[Lorg.aspectj.weaver.AnnotationAJ;
3015:             1             16  com.alibaba.fastjson.parser.deserializer.CharArrayDeserializer
3016:             1             16  com.alibaba.fastjson.parser.deserializer.ClassDerializer
3017:             1             16  com.alibaba.fastjson.parser.deserializer.CollectionDeserializer
3018:             1             16  com.alibaba.fastjson.parser.deserializer.DateDeserializer
3019:             1             16  com.alibaba.fastjson.parser.deserializer.DateFormatDeserializer
3020:             1             16  com.alibaba.fastjson.parser.deserializer.JSONArrayDeserializer
3021:             1             16  com.alibaba.fastjson.parser.deserializer.JSONObjectDeserializer
3022:             1             16  com.alibaba.fastjson.parser.deserializer.JavaObjectDeserializer
3023:             1             16  com.alibaba.fastjson.parser.deserializer.Jdk8DateCodec
3024:             1             16  com.alibaba.fastjson.parser.deserializer.MapDeserializer
3025:             1             16  com.alibaba.fastjson.parser.deserializer.NumberDeserializer
3026:             1             16  com.alibaba.fastjson.parser.deserializer.SqlDateDeserializer
3027:             1             16  com.alibaba.fastjson.parser.deserializer.StackTraceElementDeserializer
3028:             1             16  com.alibaba.fastjson.parser.deserializer.TimeDeserializer
3029:             1             16  com.alibaba.fastjson.parser.deserializer.TimestampDeserializer

jmap -dump:format=b,file=文件名 [pid]

[root@fengniaoweb home]# jmap -dump:format=b,file=heapsim 2865  
Dumping heap to /home/heapsim ...
Heap dump file created
[root@fengniaoweb home]# ls
apollo  heapsim
[root@fengniaoweb home]# 

在当前目录下生成内存dump文件

二、内存快照分析工具

jhat java自带的内存快照分析工具 一般不常用,因为有本机内存限制,不易于分析大内存文件

eclipse Memory Analyzer

Eclipse 提供的一个用于分析JVM 堆Dump文件的插件。借助这个插件可查看对象的内存占用状况,引用关系,分析内存泄露等。

具体的分析过程不作为本文讨论重点,这里就不详细讨论了。

三、kill -3 [pid] 输出线程堆栈信息

当系统负载较高响应较慢的时候或者未安装jstack命令时可以使用该命令打印java进程堆栈信息。

  • 如果项目通过Tomcat进行发布(普通的web项目),则对应的堆栈信息会打印在catalina.out文件中。

  • 如果项目是基于SpringBoot并且使用nohup java -jar xxx.jar & 命令运行,则java堆栈信息会在jar包所在的nohup.out文件中。

注意:该命令并不会杀死jvm进程

[root@fengniaoweb logs]# kill -3 2865
// 在nohup文件中发现如下堆栈信息
"JDWP Event Helper Thread" #6 daemon prio=10 os_prio=0 tid=0x00007f80c818f000 nid=0xb3c runnable [0x0000000000000000]
 java.lang.Thread.State: RUNNABLE
​
"JDWP Transport Listener: dt_socket" #5 daemon prio=10 os_prio=0 tid=0x00007f80c818b800 nid=0xb3b runnable [0x0000000000000000]
 java.lang.Thread.State: RUNNABLE
​
"Signal Dispatcher" #4 daemon prio=9 os_prio=0 tid=0x00007f80c817f800 nid=0xb3a waiting on condition [0x0000000000000000]
 java.lang.Thread.State: RUNNABLE
​
"Finalizer" #3 daemon prio=8 os_prio=0 tid=0x00007f80c814d800 nid=0xb39 in Object.wait() [0x00007f80cc16c000]
 java.lang.Thread.State: WAITING (on object monitor)
 at java.lang.Object.wait(Native Method)
 at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:144)
 - locked <0x00000000f008a960> (a java.lang.ref.ReferenceQueue$Lock)
 at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:165)
 at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:216)
​
"Reference Handler" #2 daemon prio=10 os_prio=0 tid=0x00007f80c814a800 nid=0xb38 in Object.wait() [0x00007f80b1f31000]
 java.lang.Thread.State: WAITING (on object monitor)
 at java.lang.Object.wait(Native Method)
 at java.lang.Object.wait(Object.java:502)
 at java.lang.ref.Reference.tryHandlePending(Reference.java:191)
 - locked <0x00000000f008a990> (a java.lang.ref.Reference$Lock)
 at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153)
​
"VM Thread" os_prio=0 tid=0x00007f80c8141000 nid=0xb37 runnable 
​
"GC task thread#0 (ParallelGC)" os_prio=0 tid=0x00007f80c8021000 nid=0xb33 runnable 
​
"GC task thread#1 (ParallelGC)" os_prio=0 tid=0x00007f80c8022800 nid=0xb34 runnable 
​
"GC task thread#2 (ParallelGC)" os_prio=0 tid=0x00007f80c8024800 nid=0xb35 runnable 
​
"GC task thread#3 (ParallelGC)" os_prio=0 tid=0x00007f80c8026800 nid=0xb36 runnable

四、 jstack [pid] jvm自带的堆栈工具

通过该工具可以看到JVM 中线程的运行状况,包括锁等待,线程是否在运行,线程的所有堆栈信息

[root@fengniaoweb logs]# jstack 2865
Attaching to process ID 2865, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.211-b12
Deadlock Detection:
​
No deadlocks found.
​
Thread 20440: (state = BLOCKED)
​
​
Thread 11659: (state = BLOCKED)
 - java.lang.Object.wait(long) @bci=0 (Compiled frame; information may be imprecise)
 - java.lang.ref.ReferenceQueue.remove(long) @bci=59, line=144 (Compiled frame)
 - java.lang.ref.ReferenceQueue.remove() @bci=2, line=165 (Compiled frame)
 - org.apache.commons.httpclient.MultiThreadedHttpConnectionManager$ReferenceQueueThread.run() @bci=10, line=1122 (Interpreted frame)
​
​
Thread 10425: (state = BLOCKED)
 - java.lang.Object.wait(long) @bci=0 (Compiled frame; information may be imprecise)
 - java.lang.ref.ReferenceQueue.remove(long) @bci=59, line=144 (Compiled frame)
 - com.mysql.jdbc.AbandonedConnectionCleanupThread.run() @bci=10, line=64 (Compiled frame)
 - java.util.concurrent.ThreadPoolExecutor.runWorker(java.util.concurrent.ThreadPoolExecutor$Worker) @bci=95, line=1149 (Interpreted frame)
 - java.util.concurrent.ThreadPoolExecutor$Worker.run() @bci=5, line=624 (Interpreted frame)
 - java.lang.Thread.run() @bci=11, line=748 (Interpreted frame)
​
​
Thread 10424: (state = BLOCKED)
 - java.lang.Object.wait(long) @bci=0 (Compiled frame; information may be imprecise)
 - java.util.TimerThread.mainLoop() @bci=201, line=552 (Compiled frame)
 - java.util.TimerThread.run() @bci=1, line=505 (Interpreted frame)
​
​
Thread 2866: (state = BLOCKED)
​
​
Thread 3079: (state = BLOCKED)
 - java.lang.Thread.sleep(long) @bci=0 (Compiled frame; information may be imprecise)
 - org.apache.coyote.AbstractProtocol$AsyncTimeout.run() @bci=10, line=1133 (Compiled frame)
 - java.lang.Thread.run() @bci=11, line=748 (Interpreted frame)
​
​
Thread 3078: (state = IN_NATIVE)
 - sun.nio.ch.ServerSocketChannelImpl.accept0(java.io.FileDescriptor, java.io.FileDescriptor, java.net.InetSocketAddress[]) @bci=0 (Compiled frame; information may be imprecise)
 - sun.nio.ch.ServerSocketChannelImpl.accept(java.io.FileDescriptor, java.io.FileDescriptor, java.net.InetSocketAddress[]) @bci=4, line=422 (Compiled frame)
 - sun.nio.ch.ServerSocketChannelImpl.accept() @bci=130, line=250 (Compiled frame)
 - org.apache.tomcat.util.net.NioEndpoint$Acceptor.run() @bci=88, line=455 (Interpreted frame)
 - java.lang.Thread.run() @bci=11, line=748 (Interpreted frame)
​
​
Thread 3077: (state = IN_NATIVE)
 - sun.nio.ch.EPollArrayWrapper.epollWait(long, int, long, int) @bci=0 (Compiled frame; information may be imprecise)
 - sun.nio.ch.EPollArrayWrapper.poll(long) @bci=18, line=269 (Compiled frame)
 - sun.nio.ch.EPollSelectorImpl.doSelect(long) @bci=28, line=93 (Compiled frame)
 - sun.nio.ch.SelectorImpl.lockAndDoSelect(long) @bci=37, line=86 (Compiled frame)
 - sun.nio.ch.SelectorImpl.select(long) @bci=30, line=97 (Compiled frame)
 - org.apache.tomcat.util.net.NioEndpoint$Poller.run() @bci=55, line=793 (Compiled frame)
 - java.lang.Thread.run() @bci=11, line=748 (Interpreted frame)
​
​
Thread 3076: (state = IN_NATIVE)
 - sun.nio.ch.EPollArrayWrapper.epollWait(long, int, long, int) @bci=0 (Compiled frame; information may be imprecise)
 - sun.nio.ch.EPollArrayWrapper.poll(long) @bci=18, line=269 (Compiled frame)
 - sun.nio.ch.EPollSelectorImpl.doSelect(long) @bci=28, line=93 (Compiled frame)
 - sun.nio.ch.SelectorImpl.lockAndDoSelect(long) @bci=37, line=86 (Compiled frame)
 - sun.nio.ch.SelectorImpl.select(long) @bci=30, line=97 (Compiled frame)
 - org.apache.tomcat.util.net.NioEndpoint$Poller.run() @bci=55, line=793 (Compiled frame)
 - java.lang.Thread.run() @bci=11, line=748 (Interpreted frame)

关于jstack命令的详细讲解可以参考

https://www.cnblogs.com/xingzc/p/5778010.html

附加:

命令格式 top -Hp pid -d 1 -n 1

打印进程号为pid的进程所有子线程的cpu,内存等资源占用情况。

该命令结合线程堆栈可以分析线程资源占用问题

你可能感兴趣的:(java内存文件jump和线程堆栈输出)