美文网首页
JVM 问题排查

JVM 问题排查

作者: PennyWong | 来源:发表于2016-05-31 15:10 被阅读1166次

CPU使用率高

  • 找出使用率高的进程的pid
top
  • 找出使用率高的线程tpid
top -p pid -H
  • 查看使用率高的线程当前在干什么
jstack -l pid > stack.log
// 将线程的tpid转为16进制,到stack.log中查找
grep tpid stack.log -a3

GC问题

// -t:打印时间戳,1s每隔1秒打印一次
jstat -gcutil -t pid 1s

也可以通过查看gc日志来观察问题

内存泄漏

  1. 执行FullGC后不能回收的内存不断增加
  2. 执行jstat -gcutil pid,查看Old区的使用情况,如果接近100%,则代表内存不足。可以先增大内存,如果还是不断增长到溢出,则考虑是否有内存泄漏问题
  3. 执行jmap -histo:live pid > memory.log,统计所有存活对象的个数,观察那些数量最多的对象,特别是自己写的对象和存放到集合里没有释放的对象
  4. 如果还是无法定位,则执行jmap -dump导出整个Heap,然后使用工具进行分析,注意看自己写的类的依赖关系,看看是不是使用完没有释放,或者一次性查询过多的数据导致内存溢出

线程分析

如果CPU使用率不高,但程序性能低下,则可考虑对线程进行分析,看看各个主要的线程都在做什么,是否有锁争用或IO阻塞问题

为了方便分析,最好给每个线程或者线程池命名

jstack -l pid > stack.log

线程状态

状态 描述
New 线程刚被创建,还没有被执行
Runnable 线程正在执行
Blocked 等待其他线程释放锁
Waiting 调用了wait或join方法,无限等待
Timed_Waiting 调用了sleep、wait(interval)、join(interval)方法,有限等待

观察

死锁

如果JVM发现有死锁存在,会在日志中出现Found one Java-level deadlock

Waiting on condition

在等待一个条件的发生,来把自己唤醒,或者调用了sleep方法
此时线程状态:
WAITING(parking):一直等待那个条件发生
TIMED_WAITING(parking或sleeping):定时等待,即使条件不发生,时间到了也可以自己唤醒

如果发现大量线程处于此状态,并且从线程的堆栈上查看到是正在执行网络读写,这可能是一个网络瓶颈问题或者第三方响应慢的问题

Blocked

线程所需要的资源长时间等待却一直无法获取,被标识为阻塞状态,可以理解为等待资源超时的线程。线程堆栈中一般存在Waiting to Lock

Waiting for monitor entry 和 in Object.wait()

每个 Monitor在某个时刻,只能被一个线程拥有,该线程就是Active Thread,而其它线程都是Waiting Thread,分别在两个队列 Entry Set和Wait Set里面等候。 在Entry Set中等待的线程状态是Waiting for monitor entry,而在Wait Set中等待的线程状态是in Object.wait()。当被调用notify或notifyAll时,只有在Wait Set中的线程会被唤醒

Waiting for monitor entry:等待进入一个临界区 ,所以它在Entry Set队列中等待。此时线程状态一般都是Blocked,如果存在大量线程在此状态,可能是一个全局锁阻塞住了大量线程。随着时间流逝,waiting for monitor entry的线程越来越多,没有减少的趋势,可能意味着某些线程在临界区里呆的时间太长了,以至于越来越多新线程迟迟无法进入临界区

当线程获得了Monitor,如果发现线程继续运行的条件没有满足,它则调用对象(一般就是被 synchronized 的对象)的 wait() 方法,放弃了Monitor,进入Wait Set队列。此时线程状态大致为以下几种:TIMED_WAITING (on object monitor)和 WAITING (on object monitor)

等待IO

有时候线程状态是Runnable,但却是在等待IO

"socketReadThread" prio=6 tid=0x0000000006a0d800 nid=0x1b40 runnable
[0x00000000089ef000] java.lang.Thread.State: RUNNABLE
    at java.net.SocketInputStream.socketRead0(Native Method) 

总结

  1. 如果cpu使用率不高,但性能低下,一般都是由锁或IO阻塞造成,这时要注意查看状态为BLOCKED或者Waiting的线程,看它们需要等待什么锁或者是否出现了死锁,再考虑如何优化并发
  2. 如果发现有大量的线程都在处在 Wait on condition,从线程 stack看,正等待网络读写,这可能是一个网络瓶颈的征兆。因为网络阻塞导致线程无法执行。一种情况是网络非常忙,几乎消耗了所有的带宽,仍然有大量数据等待网络读写;另一种情况也可能是网络空闲,但由于路由等问题,导致包无法正常的到达

参考

性能分析之– JAVA Thread Dump 分析综述
三个实例演示 Java Thread Dump 日志分析

相关文章

  • 一次完整的JVM堆外内存泄漏故障排查记录

    前言 记录一次线上JVM堆外内存泄漏问题的排查过程与思路,其中夹带一些JVM内存分配机制以及常用的JVM问题排查指...

  • JVM 问题排查

    CPU使用率高 找出使用率高的进程的pid 找出使用率高的线程tpid 查看使用率高的线程当前在干什么 GC问题 ...

  • JVM问题排查

    一、线上CPU飚高、死锁等排查基本步骤: 1、top 记录CPU使用率最高的JAVA进程PID 2、top -H...

  • JVM问题排查

    一、JVM的参数类型 1.Boolean类型 格式:-XX:[+-]表示启用或者禁用name属性。比如...

  • jvm问题排查

    写在前面 线上系统中:如果突然运行缓慢,CPU 100%,以及Full GC次数过多的问题,最终导致的直观现象就是...

  • JVM问题排查实战系列

    JVM问题排查实战 记一次频繁FGC的简单排查 一次JVM GC长暂停的排查过程 如何使用MAT进行内存泄露分析

  • JVM问题常用排查命令

    JVM问题常用排查命令 @Date 2017.05.23 JVM调优问题 CPU使用率与Load值偏大 : Thr...

  • 记一次OOM查询处理过程

    问题的爆出及分析排查现场 排查后的解决方案 项目的jvm参数 总结 一、问题的爆出及分析排查现场 服务偶尔会出现不...

  • JVM GC问题排查

    线上发生MQ消费延时报警,看业务log发现有几秒钟一行日志都没有,,参考历史情况这种情况不可能出现(发生报警是在业...

  • 8、线上问题排查

    文章主要列出了常见的排查工具,也有部分线上问题案例; JVM 问题排查 JDK工具包 javap 反编译工具jav...

网友评论

      本文标题:JVM 问题排查

      本文链接:https://www.haomeiwen.com/subject/qtgcdttx.html