jstat&jmap&jhat ゞ 浴缸里的玫瑰 2023-02-18 14:08 44阅读 0赞 > * 查看和设置JVM的运行参数:[https://yuanyu.blog.csdn.net/article/details/106813541][https_yuanyu.blog.csdn.net_article_details_106813541] # 1 jstat堆内存统计分析 # jstat命令可以查看堆内存各部分的使用量,以及加载类的数量,格式: jstat \[-命令选项\] \[vmid\] \[间隔时间/毫秒\] \[查询次数\] ### 查看tomcat进程号 λ jps -l 17612 org.apache.catalina.startup.Bootstrap ## 1.1 查看class加载统计 ## λ jstat -class 17612 Loaded Bytes Unloaded Bytes Time 2731 5377.9 0 0.0 2.17 <table> <tbody> <tr> <td>Loaded</td> <td>加载class的数量</td> </tr> <tr> <td>Bytes</td> <td>所占用空间大小</td> </tr> <tr> <td>Unloaded</td> <td>未加载数量</td> </tr> <tr> <td>Bytes</td> <td>未加载占用空间</td> </tr> <tr> <td>Time</td> <td>时间</td> </tr> </tbody> </table> ## 1.2 查看编译统计 ## λ jstat -compiler 17612 Compiled Failed Invalid Time FailedType FailedMethod 1812 0 0 2.48 0 <table> <tbody> <tr> <td style="width:484px;">Compiled</td> <td style="width:415px;">编译数量</td> </tr> <tr> <td style="width:484px;">Failed</td> <td style="width:415px;">失败数量</td> </tr> <tr> <td style="width:484px;">Invalid</td> <td style="width:415px;">不可用数量</td> </tr> <tr> <td style="width:484px;">Time</td> <td style="width:415px;">时间</td> </tr> <tr> <td style="width:484px;">FailedType</td> <td style="width:415px;">失败类型</td> </tr> <tr> <td style="width:484px;">FailedMethod</td> <td style="width:415px;">失败的方法</td> </tr> </tbody> </table> ## 1.3 垃圾回收统计 ## λ jstat -gc 17612 S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT 10752.0 10752.0 0.0 10740.9 65536.0 21705.0 175104.0 555.6 16768.0 16044.9 1920.0 1792.4 1 0.010 0 0.000 0.010 ### 也可以指定打印的间隔和次数,每1秒中打印一次,共打印5次 jstat -gc <pid> 1000 5 <table> <tbody> <tr> <td style="width:439px;">S0C</td> <td style="width:460px;">第一个Survivor区的大小(KB)</td> </tr> <tr> <td style="width:439px;">S1C</td> <td style="width:460px;">第二个Survivor区的大小(KB)</td> </tr> <tr> <td style="width:439px;">S0<span style="color:#f33b45;">U</span></td> <td style="width:460px;">第一个Survivor区的<span style="color:#f33b45;">使用</span>大小(KB)</td> </tr> <tr> <td style="width:439px;">S1U</td> <td style="width:460px;">第二个Survivor区的<span style="color:#f33b45;">使用</span>大小(KB)</td> </tr> <tr> <td style="width:439px;">EC</td> <td style="width:460px;">Eden区的大小(KB)</td> </tr> <tr> <td style="width:439px;">EU</td> <td style="width:460px;">Eden区的<span style="color:#f33b45;">使用</span>大小(KB)</td> </tr> <tr> <td style="width:439px;">OC</td> <td style="width:460px;">Old区大小(KB)</td> </tr> <tr> <td style="width:439px;">OU</td> <td style="width:460px;">Old使用大小(KB)</td> </tr> <tr> <td style="width:439px;">MC</td> <td style="width:460px;">方法区大小(KB)</td> </tr> <tr> <td style="width:439px;">MU</td> <td style="width:460px;">方法区使用大小(KB)</td> </tr> <tr> <td style="width:439px;">CCSC</td> <td style="width:460px;">压缩类空间大小(KB)</td> </tr> <tr> <td style="width:439px;">CCSU</td> <td style="width:460px;">压缩类空间使用大小(KB)</td> </tr> <tr> <td style="width:439px;">YGC</td> <td style="width:460px;">年轻代垃圾回收次数</td> </tr> <tr> <td style="width:439px;">YGCT</td> <td style="width:460px;">年轻代垃圾回收消耗时间</td> </tr> <tr> <td style="width:439px;">FGC</td> <td style="width:460px;">老年代垃圾回收次数</td> </tr> <tr> <td style="width:439px;">FGCT</td> <td style="width:460px;">老年代垃圾回收消耗时间</td> </tr> <tr> <td style="width:439px;">GCT</td> <td style="width:460px;">垃圾回收消耗总时间</td> </tr> </tbody> </table> ## 1.4 jstack获取线程快照 ## 有些时候我们需要查看下jvm中的线程执行情况,比如,发现服务器的CPU的负载突然增 高了、出现了死锁、死循环等,我们该如何分析呢? 由于程序是正常运行的,没有任何的输出,从日志方面也看不出什么问题,所以就需要看下jvm的内部线程的执行情况,然后再进行分析查找出原因。 这个时候,就需要借助于jstack命令了,jstack的作用是将正在运行的jvm的线程情况进行快照,并且打印出来 ### 用法 jstack <pid> ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQwNzk0OTcz_size_16_color_FFFFFF_t_70][] -------------------- # 2 jmap获取详细内容 # jstat可以对jvm堆的内存进行统计分析,而jmap可以获取到更加详细的内容, 比如内存使用情况的汇总、对内存溢出的定位与分析 ## 2.1 查看内存使用情况 ## λ jmap -heap 17612 ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQwNzk0OTcz_size_16_color_FFFFFF_t_70 1][] ## 2.2 查看内存中对象数量及大小 ## ### 查看所有对象,包括活跃以及非活跃的 jmap -histo <pid> | more ### 查看活跃对象 jmap -histo:live <pid> | more λ jmap -histo:live 17612 | more num #instances #bytes class name ---------------------------------------------- 1: 27130 2853888 [C 2: 1177 782216 [B 3: 26502 636048 java.lang.String 4: 5651 497288 java.lang.reflect.Method 5: 14170 453440 java.util.HashMap$Node 6: 3033 343168 java.lang.Class 7: 3744 211912 [Ljava.lang.Object; 8: 5924 189568 java.util.concurrent.ConcurrentHashMap$Node 9: 1063 170544 [Ljava.util.HashMap$Node; <table> 对象说明 <tbody> <tr> <td>B</td> <td>byte</td> </tr> <tr> <td>C</td> <td>char</td> </tr> <tr> <td>D</td> <td>double</td> </tr> <tr> <td>F</td> <td>float</td> </tr> <tr> <td>I</td> <td>int</td> </tr> <tr> <td>J</td> <td>long</td> </tr> <tr> <td>Z</td> <td>boolean</td> </tr> <tr> <td>[ 数组</td> <td>例如,[I表示int[]</td> </tr> <tr> <td>[L+类名</td> <td>其他对象</td> </tr> </tbody> </table> ## 2.3 将内存使用情况dump到文件中 ## 有些时候我们需要将jvm当前内存中的情况dump到文件中,然后对它进行分析,jmap也是支持dump到文件中的 ### 用法 jmap -dump:format=b,file=dumpFileName <pid> ### 示例 jmap -dump:format=b,file=/tmp/dump.dat <pid> λ jmap -dump:format=b,file=tomcat.dat 17612 Dumping heap to C:\Users\yuanyu\Desktop\tomcat.dat ... Heap dump file created -------------------- # 3 jhat对dump文件进行分析 # 在上一小节中,我们将jvm的内存dump到文件中,这个文件是一个二进制的文件,不方便查看,这时我们可以借助于jhat工具进行查看 ### 用法 jhat -port <port> <file> λ jhat -port 9999 tomcat.dat Reading from tomcat.dat... Dump file created Thu Jun 18 10:18:13 CST 2020 Snapshot read, resolving... Resolving 170319 objects... Chasing references, expect 34 dots.................................. Eliminating duplicate references.................................. Snapshot resolved. Started HTTP server on port 9999 Server is ready. ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQwNzk0OTcz_size_16_color_FFFFFF_t_70 2][] ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQwNzk0OTcz_size_16_color_FFFFFF_t_70 3][] select s from java.lang.String s where s.value.length >= 5000 ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQwNzk0OTcz_size_16_color_FFFFFF_t_70 4][] -------------------- # 4 案例演示 # ## **4.1 jps&**jstack**死锁分析** ## 如果在生产环境发生了死锁,我们将看到的是部署的程序没有任何反应了,这个时候我 们可以借助jstack进行分析 ### 4.1.1 线程的6种状态 ### > 在Java中线程的状态一共被分成6种 > > 初始态(NEW) > > * 创建一个Thread对象,但还未调用start()启动线程时,线程处于初始态 > > 运行态(RUNNABLE),在Java中运行态包括 就绪态 和 运行态 > > * **就绪态** : 该状态下的线程已经获得执行所需的所有资源,只要CPU分配执行权就能运行;所有就绪态的线程存放在**就绪队列**中 > * **运行态** : 获得CPU执行权,正在执行的线程;由于一个CPU同一时刻只能执行一条线程,因此每个CPU每个时刻只有一条运行态的线程 > > 阻塞态(BLOCKED) > > * 当一条正在执行的线程请求某一资源失败时,就会进入阻塞态 > * 而在Java中,阻塞态专指请求锁失败时进入的状态 > * 由一个**阻塞队列**存放所有阻塞态的线程 > * 处于阻塞态的线程会不断请求资源,一旦请求成功,就会进入就绪队列,等待执行 > > 等待态(WAITING) > > * 当前线程中调用wait、join、park函数时,当前线程就会进入等待态 > * 也有一个**等待队列**存放所有等待态的线程 > * 线程处于等待态表示它需要等待其他线程的指示才能继续运行 > * 进入等待态的线程会释放CPU执行权,并释放资源(如:锁) > > 超时等待态(TIMED\_WAITING) > > * 当运行中的线程调用sleep(time)、wait、join、parkNanos、parkUntil时,就会进入该状态 > * 它和等待态一样,并不是因为请求不到资源,而是主动进入,并且进入后需要其他线程唤醒 > * 进入该状态后释放CPU执行权和占有的资源 > * 与等待态的区别:到了超时时间后自动进入阻塞队列,开始竞争锁 > > 终止态(TERMINATED) > > * 线程执行结束后的状态 ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQwNzk0OTcz_size_16_color_FFFFFF_t_70 5][] ### 4.1.2 构造死锁 ### /** * 必定发生死锁的情况 */ public class MustDeadLock implements Runnable { static final Object LOCK_A = new Object(); static final Object LOCK_B = new Object(); @Override public void run() { System.out.println(Thread.currentThread().getName() + "进入了run方法..."); if ("A".equals(Thread.currentThread().getName())) { synchronized (LOCK_A) { try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (LOCK_B) { System.out.println("线程A成功拿到两把锁"); } } } if ("B".equals(Thread.currentThread().getName())) { synchronized (LOCK_B) { try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (LOCK_A) { System.out.println("线程B成功拿到两把锁"); } } } } public static void main(String[] args) { MustDeadLock run = new MustDeadLock(); Thread t1 = new Thread(run, "A"); Thread t2 = new Thread(run, "B"); t1.start(); t2.start(); } } ### 4.1.3 使用jstack进行分析 ### ### 查询到pid λ jps -l 14148 MustDeadLock ### λ jstack 14148 ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQwNzk0OTcz_size_16_color_FFFFFF_t_70 6][] [https_yuanyu.blog.csdn.net_article_details_106813541]: https://yuanyu.blog.csdn.net/article/details/106813541 [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQwNzk0OTcz_size_16_color_FFFFFF_t_70]: https://img-blog.csdnimg.cn/20201005134146941.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQwNzk0OTcz,size_16,color_FFFFFF,t_70 [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQwNzk0OTcz_size_16_color_FFFFFF_t_70 1]: https://img-blog.csdnimg.cn/20200618100430245.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQwNzk0OTcz,size_16,color_FFFFFF,t_70 [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQwNzk0OTcz_size_16_color_FFFFFF_t_70 2]: https://img-blog.csdnimg.cn/20200618102822997.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQwNzk0OTcz,size_16,color_FFFFFF,t_70 [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQwNzk0OTcz_size_16_color_FFFFFF_t_70 3]: https://img-blog.csdnimg.cn/20200618102936248.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQwNzk0OTcz,size_16,color_FFFFFF,t_70 [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQwNzk0OTcz_size_16_color_FFFFFF_t_70 4]: https://img-blog.csdnimg.cn/20200618103417226.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQwNzk0OTcz,size_16,color_FFFFFF,t_70 [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQwNzk0OTcz_size_16_color_FFFFFF_t_70 5]: https://img-blog.csdnimg.cn/20200618111301867.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQwNzk0OTcz,size_16,color_FFFFFF,t_70 [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQwNzk0OTcz_size_16_color_FFFFFF_t_70 6]: https://img-blog.csdnimg.cn/20201005111945680.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQwNzk0OTcz,size_16,color_FFFFFF,t_70
还没有评论,来说两句吧...