原文地址: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)
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飙高的线程问题相关推荐
- 你要偷偷学会排查线上 CPU 飙高的问题,然后惊艳所有人!
作者 l Hollis 来源 l Hollis(ID:hollischuang) 前段时间我们新上了一个新的应用,因为流量一直不大,集群QPS大概只有5左右,写接口的rt在30ms左右. 因为最近接入 ...
- java进程CPU飙高
早上某段时间突然看到看到一台生产机器上的CPU飙高 top 然后就请出了大神工具JVM 具体JVM的介绍看:http://www.cnblogs.com/smail-bao/p/6027756.htm ...
- java单核cpu飙高考死_java多线程在单核CPU上,还是需要volatile synchronized吗?
本来不想回答的,可是看了这么多答案,有的不是特别靠谱.斗胆写个粗略的回答. 首先,JMM是不区分是否JVM到底是运行在单核处理器.单核超线程处理器.多核处理器,抑或是多核超线程处理器上的.就是说,Ja ...
- JVM中如何排查CPU飙高的问题
1.虚拟机对象布局 布局:对象头.实例数据.对齐填充 对象头: Mark Word 8字节,hashcode值.GC分代信息.偏向锁信息: Class Po ...
- 面试官:线上服务CPU飙高怎么排查?
用jstack排查 先执行top,找到CPU占用比较高的进程 jstack 进程id > show.txt 找到进程中CPU占用比较高的线程,线程id转为16进制 到show.txt文件中根据线 ...
- CPU 飙高问题排查和解决方法
摘要 本文档记录了排查 CPU 飙高问题的处理过程和解决方法,从多个方面进行分析和排查. 问题简述 在一个生产环境中发现 CPU 飙高问题,但是无法确定问题的具体原因. 排查方法 使用 jstack ...
- 简单的cpu飙高问题定位脚本
原文链接: https://blog.csdn.net/manzhizhen/article/details/79333676 老司机在定位和解决问题时都有着自己的一套方法论,总不能老踩一些重复的坑是 ...
- linux服务器CPU飙高排查
文章目录 前言 一.第一步 top 二.根据pid查找具体线程 2.根据pid找到16进制 3. 根据进程和线程查找原因 总结 前言 系统cpu飙高,尤其对于后端人员来说,其实应该学会排查,这样也算是 ...
- 面试官问:平时碰到系统CPU飙高和频繁GC,你会怎么排查?
点击上方"方志朋",选择"设为星标" 做积极的人,而不是积极废人 处理过线上问题的同学基本上都会遇到系统突然运行缓慢,CPU 100%,以及Full GC次数过 ...
最新文章
- ipv6下单播。组播 泛播
- 快速启动神器 Wox
- nc65数据字典 云盘_从搜索引擎到核心交易数据库,详解阿里云神龙如何支撑双11...
- Dalvik内存管理
- windows 下win+r无效
- 我女朋友让我删前任,我明明删了她还是要分手...
- 少儿编程150讲轻松学Scratch(十一)-用Scratch算法给矩形工具填充颜色
- 测试方案_在线式UPS电源测试方案
- 使用MEMCACHED的思考
- DPDK - mlx5 drop action 性能 patch
- FPGA驱动USB协议芯片的测试
- rfid破解 BLE Hacking
- python+django酒店客房餐饮管理系统vue源码
- Excise_Oop2
- Django由一查多
- 可怜的码农们该如何赚钱?
- 在Linux上测试网络的命令之3----基础网络命令(netstat\ss)
- 用8266学习单片机-13-HC-SR04超声波模块测距示例-Ultrasonic-US-015
- bazaar android app,Bazaart
- 什么是继承,什么是多态,方法的重载和覆盖有何区别?
热门文章
- 计算机无法启动安装程序,安装Win10系统提示安装程序无法正常启动怎么办
- 苹果新产品中的机器学习算法
- H5电玩城源码+玩法比较多+UI也特别好看+纯源码系列
- tipask mysql调取dedecms_帝国CMS如何在首页调用tipask最新问题-DEDE
- 服务器固态硬盘接口区别,s s d固态硬盘和服务器配件硬盘的区别
- JAVA生成甘特图Excel导出
- Ubantu搭建深度学习和强化学习环境
- 确定十二星座的日期范围
- Spring MVC+Spring+Mybatis
- Hangfire详解