如何分析线程Dump和堆Dump

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/GoGleTech/article/details/84111933

先上图,下面是一个线程Dump:
在这里插入图片描述

1、线程Dump的各种概念:

线程的状态:

  • NEW:未启动,不会出现在Dump中
  • RUNNABLE:在虚拟机中执行的
  • BLOCKED:受阻塞并等待在监视器锁
  • WAITTING:无限期等待另一个线程执行特定的操作
  • TIMED_WAITTING:有时限的等候另一个线程执行特定的操作
  • TERMINATED:已退出

什么是监视器:

面向对象锁控制访问这个锁的线程的一个线程。
在这里插入图片描述

调用修饰:

  • locked <地址> 目标:注意临界区对象锁可重入,线程状态为RUNNABLE
  • waitting to lock <地址> 目标:还没有获得锁,进入区等待,线程状态为BLOCKED
  • waitting on <地址> 目标:获得锁了,等待区等待,线程状态为WAITTING,TIMED_WAITTING
  • parking to wait for <地址> 目标:线程原语,随current包出现,与synchronized体系不同

线程动作

  • runnable:线程状态为RUNNABLE
  • in Object.wait():等待区等待,线程状态为WAITTING或TIMED_WAITTING
  • waitting for monitor entry:进入区等待,线程状态为BLOCKED
  • waitting on condition:等待区等待,被park
  • sleeping:休眠的线程,调用了Thread.sleep()

2、分析线程Dump的入手点

1、进入区等待:BLOCKED、waitting to lock、waitting for monitor entry,这些词表名代码层面已经存在冲突。

2、持续进行的IO:一般来说被捕捉到的runnable的IO调用都是有问题的,如runnable中有JDBC链接的代码

3、非线程调度的等待区等待:in Object.wait()(情况1可能会导致这个情况,造成大量线程堆积)

3、“死锁”问题的解决办法

1、在最可能死锁的时间点制作Dump

2、找出引起大量线程阻塞的线程

扫描二维码关注公众号,回复: 5448665 查看本文章

3、找出该线程阻塞的原因

4、阅读代码,遍历其他阻塞或等待的线程,以及它之前的调用是否会造成这个线程的等待

4、注意

排除GC干扰,Full GC时所有线程都会被阻塞住,

  • 查看线程Dump时,首先查看内存使用情况
  • 使用命令“-verbose:gc”,观察是否有Full GC字样

5、什么情况下需要分析堆Dump

内存不足、GC异常、怀疑代码内存泄漏,这时需要制作堆Dump,找出生命周期的错误关联对象以及相关代码。

6、内存模型

年轻代(Young Generation,包括Eden space、From space、To space)
年老代(Old Generation)
永久代(PermGen space)

两种GC:

  • YoungGen GC:Minor GC
  • Full GC:Major GC

7、内存泄漏和内存溢出

  • 内存泄漏:好比画画时把整个本都画满了,没地方画了。
    一个对象持有一个引用永远不释放,导致声明周期过长,这样持有的对象对了,内存就不够用了,这样就会频繁GC
  • 内存溢出:画画时把一整页都画满了,都画到桌子上了。

8、常见错误

  • out of MemoryError:GC overhead limit exceed
    回收时间占系统运行时间的98%以上,极有可能是内存泄漏导致的。

猜你喜欢

转载自blog.csdn.net/GoGleTech/article/details/84111933