原文地址:https://www.cnblogs.com/zyhxhx/p/4564953.html

1. 获取要查看的进程的ID

ps aux | grep xxx

2. 查看此进程下的线程信息

  • top -H -p <pid>
  • top -p <pid>      按shift+h
  • top -Hp <pid>

3. 查看栈信息

jstack <pid> > stack

  • sudo -u tomcat $JAVA_HOME/bin/jstack <pid> > stack.log
  • sudo vim-->sh-->获取root权限-->su - tomcat--> $JAVA_HOME/bin/jstack

4. 简单分析

  • 线程ID为十进制-->十六进制:printf "%x\n" xxx
  • 观察占用cpu高的线程ID
1>>若此线程ID固定不变
2>>占cpu高的线程不断变化,多观察,统计 
3>>cat stack | grep 'java.lang.Thread.State' | awk '{print $2$3$4$5}' | sort | uniq -c
562 RUNNABLE
5 TIMED_WAITING(onobjectmonitor)
174 TIMED_WAITING(parking)
7 TIMED_WAITING(sleeping)
3 WAITING(onobjectmonitor)
330 WAITING(parking)
  • 线程的state
1>>RUNNABLE: 线程正在执行中,占用了资源,比如处理某个请求/进行计算/文件操作等
2>>BLOCKED/Waiting to lock(需关注):
>>>线程处于阻塞状态,等待某种资源(可理解为等待资源超时的线程);
>>>"waiting to lock <xxx>",即等待给xxx上锁,grep stack文件找locked <xxx> 查找获得锁的线程;
>>>"waiting for monitor entry" 线程通过synchronized(obj){……}申请进入了临界区,但该obj对应的monitor被其他线程拥有,从而处于等待。
3>>WAITING/TIMED_WAITING{定时}(关注):
>>>"TIMED_WAITING (parking)":等待状态,且指定了时间,到达指定的时间后自动退出等待状态,parking指线程处于挂起中;
>>>"waiting on condition"需与堆栈中的"parking to wait for  <xxx> (atjava.util.concurrent.SynchronousQueue$TransferStack)"结合来看。first-->此线程是在等待某个条件的发生,来把自己唤醒,second-->SynchronousQueue不是一个队列,其是线程之间移交信息的机制,当我们把一个元素放入到 SynchronousQueue 中时必须有另一个线程正在等待接受移交的任务,因此这就是本线程在等待的条件。
4>>Deadlock(需关注):死锁,资源相互占用。

5. other

  • 线程状态为“waiting for monitor entry”
意味着它 在等待进入一个临界区 ,所以它在”Entry Set“队列中等待。
此时线程状态一般都是 Blocked:
java.lang.Thread.State: BLOCKED (on object monitor)
  • 线程状态为“waiting on condition”
说明它在等待另一个条件的发生,来把自己唤醒,或者干脆它是调用了 sleep(N)。
此时线程状态大致为以下几种:
java.lang.Thread.State: WAITING (parking):一直等那个条件发生;
java.lang.Thread.State: TIMED_WAITING (parking或sleeping):定时的,那个条件不到来,也将定时唤醒自己。
  • 如果大量线程在“waiting for monitor entry”
可能是一个全局锁阻塞住了大量线程。
如果短时间内打印的 thread dump 文件反映,随着时间流逝,waiting for monitor entry 的线程越来越多,没有减少的趋势,可能意味着某些线程在临界区里呆的时间太长了,以至于越来越多新线程迟迟无法进入临界区。
  • 如果大量线程在“waiting on condition”
可能是它们又跑去获取第三方资源,尤其是第三方网络资源,迟迟获取不到Response,导致大量线程进入等待状态。
所以如果你发现有大量的线程都处在 Wait on condition,从线程堆栈看,正等待网络读写,这可能是一个网络瓶颈的征兆,因为网络阻塞导致线程无法执行。
线程状态为“in Object.wait()”:
说明它获得了监视器之后,又调用了 java.lang.Object.wait() 方法。
每个 Monitor在某个时刻,只能被一个线程拥有,该线程就是 “Active Thread”,而其它线程都是 “Waiting Thread”,分别在两个队列 “ Entry Set”和 “Wait Set”里面等候。在 “Entry Set”中等待的线程状态是 “Waiting for monitor entry”,而在 “Wait Set”中等待的线程状态是 “in Object.wait()”。
当线程获得了 Monitor,如果发现线程继续运行的条件没有满足,它则调用对象(一般就是被 synchronized 的对象)的 wait() 方法,放弃了 Monitor,进入 “Wait Set”队列。
此时线程状态大致为以下几种:
java.lang.Thread.State: TIMED_WAITING (on object monitor);
java.lang.Thread.State: WAITING (on object monitor);
一般都是RMI相关线程(RMI RenewClean、 GC Daemon、RMI Reaper),GC线程(Finalizer),引用对象垃圾回收线程(Reference Handler)等系统线程处于这种状态。

6. Test

"DubboServerHandler-10.88.132.160:20088-thread-3"{线程名} daemon prio=10{优先级} tid=0x00007f2770004800{java线程ID} nid=0x1b0b{native线程ID} waiting on condition [0x00007f2445a99000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for  <0x00000005f9e9dcc8> (a java.util.concurrent.SynchronousQueue$TransferStack)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:186)
at java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:458)
at java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:359)
at java.util.concurrent.SynchronousQueue.take(SynchronousQueue.java:925)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1068)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:744)

简单排查java应用CPU飙高的线程问题相关推荐

  1. 你要偷偷学会排查线上 CPU 飙高的问题,然后惊艳所有人!

    作者 l Hollis 来源 l Hollis(ID:hollischuang) 前段时间我们新上了一个新的应用,因为流量一直不大,集群QPS大概只有5左右,写接口的rt在30ms左右. 因为最近接入 ...

  2. java进程CPU飙高

    早上某段时间突然看到看到一台生产机器上的CPU飙高 top 然后就请出了大神工具JVM 具体JVM的介绍看:http://www.cnblogs.com/smail-bao/p/6027756.htm ...

  3. java单核cpu飙高考死_java多线程在单核CPU上,还是需要volatile synchronized吗?

    本来不想回答的,可是看了这么多答案,有的不是特别靠谱.斗胆写个粗略的回答. 首先,JMM是不区分是否JVM到底是运行在单核处理器.单核超线程处理器.多核处理器,抑或是多核超线程处理器上的.就是说,Ja ...

  4. JVM中如何排查CPU飙高的问题

    1.虚拟机对象布局 布局:对象头.实例数据.对齐填充 对象头: Mark Word 8字节,hashcode值.GC分代信息.偏向锁信息:                       Class Po ...

  5. 面试官:线上服务CPU飙高怎么排查?

    用jstack排查 先执行top,找到CPU占用比较高的进程 jstack 进程id > show.txt 找到进程中CPU占用比较高的线程,线程id转为16进制 到show.txt文件中根据线 ...

  6. CPU 飙高问题排查和解决方法

    摘要 本文档记录了排查 CPU 飙高问题的处理过程和解决方法,从多个方面进行分析和排查. 问题简述 在一个生产环境中发现 CPU 飙高问题,但是无法确定问题的具体原因. 排查方法 使用 jstack ...

  7. 简单的cpu飙高问题定位脚本

    原文链接: https://blog.csdn.net/manzhizhen/article/details/79333676 老司机在定位和解决问题时都有着自己的一套方法论,总不能老踩一些重复的坑是 ...

  8. linux服务器CPU飙高排查

    文章目录 前言 一.第一步 top 二.根据pid查找具体线程 2.根据pid找到16进制 3. 根据进程和线程查找原因 总结 前言 系统cpu飙高,尤其对于后端人员来说,其实应该学会排查,这样也算是 ...

  9. 面试官问:平时碰到系统CPU飙高和频繁GC,你会怎么排查?

    点击上方"方志朋",选择"设为星标" 做积极的人,而不是积极废人 处理过线上问题的同学基本上都会遇到系统突然运行缓慢,CPU 100%,以及Full GC次数过 ...

最新文章

  1. ipv6下单播。组播 泛播
  2. 快速启动神器 Wox
  3. nc65数据字典 云盘_从搜索引擎到核心交易数据库,详解阿里云神龙如何支撑双11...
  4. Dalvik内存管理
  5. windows 下win+r无效
  6. 我女朋友让我删前任,我明明删了她还是要分手...
  7. 少儿编程150讲轻松学Scratch(十一)-用Scratch算法给矩形工具填充颜色
  8. 测试方案_在线式UPS电源测试方案
  9. 使用MEMCACHED的思考
  10. DPDK - mlx5 drop action 性能 patch
  11. FPGA驱动USB协议芯片的测试
  12. rfid破解 BLE Hacking
  13. python+django酒店客房餐饮管理系统vue源码
  14. Excise_Oop2
  15. Django由一查多
  16. 可怜的码农们该如何赚钱?
  17. 在Linux上测试网络的命令之3----基础网络命令(netstat\ss)
  18. 用8266学习单片机-13-HC-SR04超声波模块测距示例-Ultrasonic-US-015
  19. bazaar android app,Bazaart
  20. 什么是继承,什么是多态,方法的重载和覆盖有何区别?

热门文章

  1. 计算机无法启动安装程序,安装Win10系统提示安装程序无法正常启动怎么办
  2. 苹果新产品中的机器学习算法
  3. H5电玩城源码+玩法比较多+UI也特别好看+纯源码系列
  4. tipask mysql调取dedecms_帝国CMS如何在首页调用tipask最新问题-DEDE
  5. 服务器固态硬盘接口区别,s s d固态硬盘和服务器配件硬盘的区别
  6. JAVA生成甘特图Excel导出
  7. Ubantu搭建深度学习和强化学习环境
  8. 确定十二星座的日期范围
  9. Spring MVC+Spring+Mybatis
  10. Hangfire详解