帮你大致定位到现场导致LOAD飙升的JVM线程

标签: load jvm 线程 | 发表时间:2016-07-19 08:59 | 作者:j2ee_yohn
出处:http://www.iteye.com
帮你大致定位到现场导致LOAD飙升的JVM线程
大家都有过遇到线上程序LOAD突然狂飙的场景,要排查到为何狂飙,我们当务之急就是要找到导致CPU飙升的原因。如果是进程级的应用,如Nginx、Apache等都还比较容易排查,但如果是JVM中的某个线程导致的,估计有人就要开始抓瞎了。

很多人都或多或少的知道有这么一个脚本,能帮你大致定位到现场导致LOAD飙升的JVM线程,脚本大概如下。

#!/bin/sh
# write by    : [email protected]
# date        : 2014-01-16
# version    : 0.07
typeset top=${1:-10}
typeset pid=${2:-$(pgrep -u $USER java)}
typeset tmp_file=/tmp/java_${pid}_$$.trace

$JAVA_HOME/bin/jstack $pid > $tmp_file
ps H -eo user,pid,ppid,tid,time,%cpu --sort=%cpu --no-headers\
        | tail -$top\
        | awk -v "pid=$pid" '$2==pid{print $4"\t"$6}'\
        | while read line;
do
        typeset nid=$(echo "$line"|awk '{printf("0x%x",$1)}')
        typeset cpu=$(echo "$line"|awk '{print $2}')
        awk -v "cpu=$cpu" '/nid='"$nid"'/,/^$/{print $0"\t"(isF++?"":"cpu="cpu"%");}' $tmp_file
done
rm -f $tmp_file

现在我们就来拆解其中的原理,以及说明下类似脚本的适用范围。

步骤1:dump当前JVM线程,保存现场

$JAVA_HOME/bin/jstack $pid > $tmp_file

​保存现场是相当的重要,因为问题转瞬之间就会从手中溜走(但其实LOAD的统计机制也决定了,事实也并不是那么严格)

​步骤2:找到当前CPU使用占比高的线程

ps H -eo user,pid,ppid,tid,time,%cpu --sort=%cpu



列说明

USER:进程归属用户

PID:进程号

PPID:父进程号

TID:线程号

%CPU:线程使用CPU占比(这里要提醒下各位,这个CPU占比是通过/proc计算得到,存在时间差)

步骤3:合并相关信息

我们需要关注的大概是3列:PID、TID、%CPU,我们通过PS拿到了TID,可以通过进制换算10-16得到jstack出来的JVM线程号​

typeset nid="0x"$(echo "$line"|awk '{print $1}'|xargs -I{} echo "obase=16;{}"|bc|tr 'A-Z' 'a-z')

最后再将ps和jstack出来的信息进行一个匹配与合并。终于,得到我们最想要的信息



适用范围说明

看似这个脚本很牛X的样子,能直接定位到最耗费CPU的线程,开发再也不用担心找不到线上最有问题的代码~但,且慢,姑且注意下输出的结果,State: WAITING 这是这个啥节奏~

这是因为ps中的%CPU数据统计来自于/proc/stat,这个份数据并非实时的,而是取决于OS对其更新的频率,一般为1S。所以你看到的数据统计会和jstack出来的信息不一致也就是这个原因~但这份信息对持续LOAD由少数几个线程导致的问题排查还是非常给力的,因为这些固定少数几个线程会持续消耗CPU的资源,即使存在时间差,反正也都是这几个线程所导致。

这里分享下淘宝内部经常排查到的几个有问题线程,大家如果用到了又遇到LOAD突然飙高,可以优先怀疑他们。

Forest、CatServer、Notify

已有 0 人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



相关 [load jvm 线程] 推荐:

帮你大致定位到现场导致LOAD飙升的JVM线程

- - Java - 编程语言 - ITeye博客
帮你大致定位到现场导致LOAD飙升的JVM线程. 大家都有过遇到线上程序LOAD突然狂飙的场景,要排查到为何狂飙,我们当务之急就是要找到导致CPU飙升的原因. 如果是进程级的应用,如Nginx、Apache等都还比较容易排查,但如果是JVM中的某个线程导致的,估计有人就要开始抓瞎了. 很多人都或多或少的知道有这么一个脚本,能帮你大致定位到现场导致LOAD飙升的JVM线程,脚本大概如下.

线上jvm进程CPU load高排查脚本-jkiller

- - 五四陈科学院-坚信科学,分享技术
以下内容由 [五四陈科学院]提供. 如果遇到线上java进程占用过多的cpu,可以用这个脚本来帮助你快速找到代码的问题. 先用top或者是jps定位占用cpu过多的java进程的pid是多少. 然后执行如下过程即可得到结论:. *centos系统下测试通过. 想快点找到作者也可以到Twitter上留言: @54chen.

聊聊多线程程序的load balance

- - 搜索技术博客-淘宝
说起load balance,一般比较容易想到的是大型服务在多个replica之间的load balance、和kernal的load balance. 前者一般只是在流量入口做一下流量分配,逻辑相对简单;而后者则比较复杂,需要不断发现正在运行的各个进程之间的imbalance,然后通过将进程在CPU之间进行迁移,使得各个CPU都被充分利用起来.

JVM 内部运行线程介绍

- - 并发编程网 - ifeve.com
感谢同事 [觉梦]投递此稿. 最近抽时间把JVM运行过程中产生的一些线程进行了整理,主要是围绕着我们系统jstack生成的文件为参照依据.  前段时间因为系统代码问题,造成性能瓶颈,于是就dump了一份stack出来进行分析.  stack 里面线程非常多,排查起来需要一定的经验,所以,对它们有一定了解,可以提高排查问题的效率.

单个JVM下支撑100w线程数

- - Linux - 操作系统 - ITeye博客
3.Memory够大,512GB. II、测试工具:【DieLikeADog.java】. 1.ps -Lf |wc -l ==>查看某个进程中的线程数量. >>>主要查看-n,-u的值. 永久修改:将vm.max_map_count=2048000配置到/etc/sysctl.conf中,然后执行sysctl -p生效,重启os后也会持久.

关于JVM(JDK),Tomcat,Linux的最大线程数问题

- - 孟飞阳的博客
一、JVM(JDK)最大线程数. JVM最大创建线程数量由JVM堆内存大小、线程的Stack内存大小、系统最大可创建线程数(Java线程的实现是基于底层系统的线程机制来实现的,Windows下_beginthreadex,Linux下pthread_create)三个方面影响. -Xmx  最大堆内存.

JVM性能调优监控工具专题二:VisualVM基本篇之监控JVM内存,CPU,线程

- - ITeye博客
        上一个专题中讲述了JVM中自带的各种性能测试的小工具:包括jps,jstatck,jmap,jhat,jsats,hprof.         这样会造成不必要的麻烦,难道就没有一个tool可以 包括如上所有的功能. 答案是有的,自从 JDK 6 Update 7以后,提供了一全新的性能检测工具:VisualVM,VisualVM对运行中的Java应用提供了可视化的信息展示, 它是很多工具的整合包,整合了JConsole,jstat,jinfo,jstack以及jmap.

DB2数据迁移之load

- - IT技术博客大学习
标签:   2数据迁移   DB   load.      一.load原理性知识.      1.为什么要使用LOAD.      load不需要写日志(或很少日志),不做检查约束和参照完整性约束,不触发Trigger,锁的时间比较短,因此特别适合大数据量的导入..      2.load过程分为4个阶段.

Galera Load Balancer 0.9.0 正式版发布

- - 开源中国社区最新新闻
Galera Load Balancer 0.9.0 发布了,主要是引入 libglb.so ,可为你的 Linux 应用增加负载均衡能力,只需重载 libc 的 connect() 调用即可;同时提供可客户端到服务器端的直连,无处重新编译;增加了 round-robin 均衡策略. GLB (Galera Load Balancer) 是一个与 Pen 类似的 TCP 负载均衡器,它功能没有 Pen 那么强大,其主要的目的是做一个非常快速的 TCP 协议代理.

hibernate中get和load,find的区别

- - 企业架构 - ITeye博客
get和load方式是根据id取得一个记录. 下边详细说一下get和load的不同,因为有些时候为了对比也会把find加进来. 1.从返回结果上对比:. load方式检索不到的话会抛出org.hibernate.ObjectNotFoundException异常. get方法检索不到的话会返回null.