专栏首页陈黎栋的专栏啦linux进程和线程排查 · 记一次JVM CPU高负载的排查办法

linux进程和线程排查 · 记一次JVM CPU高负载的排查办法

前言

查看所有进程信息 top -H

轻量级进程(LWP)

实验观察

操作总结

htop

查看进程下的线程信息

两种命令

ps -Lf pid

pstree -p 22564

ps命令详解

ps –e | grep java

ps –o nlwp 27989

获取真正在running的线程

JVM CPU高负载的排查办法

前言

通过本文,你将学会:

1、linux上进程及进程中线程排查的基本方法,如查看进程中的线程数

此文中的线程一般指轻量级进程。

查看所有进程信息 top -H

加上-H这个选项启动top,top一行显示一个线程(指的是(轻量级)进程? )。否则,它一行显示一个进程。

先输入top -p 20378 只显示该进程的变化情况 ,但是在按H(shift + h)后,会显示threads的信息,但是总的CPU占用之和远小于没按H之前的占用之和。

轻量级进程(LWP)

轻量级进程(LWP)是一种实现多任务的方法。与普通进程相比,LWP与其他进程共享所有(或大部分)它的逻辑地址空间和系统资源;与线程相比,LWP有它自己的进程标识符,优先级,状态,以及栈和局部存储区,并和其他进程有着父子关系。

后文中的LWP粗略认为是线程。LWP的一个重要作用是提供了一个用户级线程实现的中间系统。LWP可以通过系统调用获得内核提供的服务,因此,当一个用户级线程运行时,只需要将它连接到一个LWP上便可以具有内核支持线程的所有属性。

实验观察

某个时刻下的截图

个别时间下出现CPU占用1000%,出现次数几乎可以忽略。

操作总结

一般通过top -H定位想要具体分析的Java进程对应的PID,此处为22564。

htop

install htop 一个比top更强大的命令,支持点击 %CPU %MEM后进行排序

查看进程下的线程信息

两种命令

ps -Lf pid 查看对应进程下的线程信息

pstree -p 22564 通过进程PID查看进程下线程的PID

上面两个命令的缺点: 没有线程占用资源的信息

ps -Lf pid

通过ps -Lf pid 查看对应进程下的线程信息 ,查到pid 22564下有1个进程(自身)+48个线程,如下图所示:

上图是截图左半部分

上图是截图右半部分

pstree -p 22564

pstree -p 22564 通过进程PID查看进程下线程的PID

ps命令详解

ps –e | grep java

ps命令可以查看进程状态,如执行如下命令:

ps –e | grep java

结果如下图:

可以看到,只打印了一个进程的信息;27989是线程id,java是指执行的java命令。这是因为启动一个tomcat,内部所有的工作都在这一个进程里完成,包括主线程、垃圾回收线程、Acceptor线程、请求处理线程等等。

ps –o nlwp 27989

通过ps –o nlwp 27989命令,可以看到该进程内有多少个线程;其中,nlwp含义是number of light-weight process。

获取真正在running的线程

可以看到,该进程内部有73个线程;但是73并没有排除处于idle状态的线程。要想获得真正在running的线程数量,可以通过以下语句完成:

ps -eLo pid ,stat | grep 27989 | grep running | wc -l

其中ps -eLo pid ,stat可以找出所有线程,并打印其所在的进程号和线程当前的状态;两个grep命令分别筛选进程号和线程状态;wc统计个数。其中,ps -eLo pid ,stat | grep 27989输出的结果如下:

图中只截图了部分结果;Sl表示大多数线程都处于空闲状态。

JVM CPU高负载的排查办法

今天线上一个java进程cpu负载100%。按以下步骤查出原因。

1.执行top -c命令,找到cpu最高的进程的id

2.执行top -H -p pid,这个命令就能显示刚刚找到的进程的所有线程的资源消耗情况。找到CPU负载高的线程pid 8627, 把这个数字转换成16进制,21B3(10进制转16进制,用linux命令: printf %x 8627)。

3.执行jstack -l pid,拿到进程的线程dump文件。这个命令会打出这个进程的所有线程的运行堆栈。

4.用记事本打开这个文件,搜索“21B3”,就是搜一下16进制显示的线程id。搜到后,下面的堆栈就是这个线程打出来的。排查问题从这里深入。

今天最后排查出来的结果是“VM THREAD”把进程的资源耗尽。那只能说明是jvm在耗cpu。很容易想到是疯狂的GC,按关键字 “overhead” 搜一下系统日志, 发现 “java.lang.OutOfMemoryError: GC overhead limit exceeded”日志。问题明了了。jvm在疯狂的Full GC,而且有个大对象始终根节点路径可达,无法释放。dump了一下这个实例的内存,发现确实有大对象,占用了一个多G的堆内存。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 算法学习-分治法-大整数乘法

    大整数乘法(C)请设计一个有效的算法,可以进行两个n位大整数的乘法运算。 设X和Y都是n位的二进制整数,现在要计算它们的乘积XY。我们可以用小学所学的方法来设...

    陈黎栋
  • 工作提高——《程序员思维修炼》中提到的那些点子

    我是一个习惯于多任务处理的人,因为我觉得这样子可以加快步伐,避免单一带来的枯燥。但这本书提到:

    陈黎栋
  • 编程笔记_JAVA_正则表达式工具

    java.util.regex.Pattern; //模式类:字符串要被匹配的模式

    陈黎栋
  • java并发知识点(3)-同步

    锁是可以重入的,线程可以重复获得已经持有的锁,一个被锁保护的代码可以调用另一个使用相同锁的方法

    用户2436820
  • Java并发编程--Lock

      Lock 实现提供了比使用 synchronized 方法和语句可获得的更广泛的锁定操作。synchronized方法或代码块的使用提供了对与每个对象相关的...

    在周末
  • MongoDB网络传输处理源码实现及性能调优-体验内核性能极致设计

    开源MongoDB代码规模数百万行,本篇文章内容主要分析MongoDB网络传输模块内部实现及其性能调优方法,学习网络IO处理流程,体验不同工作线程模型性能极致设...

    MongoDB中文社区
  • Flutter卡顿优化锦辑

    首先,在做性能调优之前,我们应该对flutter相关基础知识有一定的了解,不然我们无从做起,首先,我们要了解flutter是干嘛的--Flutter 是谷歌20...

    brzhang
  • SpringBoot线程池的创建、@Async配置步骤及注意事项

    最近在做订单模块,用户购买服务类产品之后,需要进行预约,预约成功之后分别给商家和用户发送提醒短信。考虑发短信耗时的情况所以我想用异步的方法去执行,于是就在网上看...

    IT大咖说
  • Java Concurrent AQS原理&源码概要(Java 10)

    开始说AQS之前,继续说上一篇没说完的建议,相对于看一些不知道时效性的blog,说实话,理解一个知识点最简便的方式就是看论文及源码实现了,解决一个问题最好的方式...

    邹志全
  • Java并发包科普

    我们通常所说的并发包也就是java.util.concurrent及其子包,集中了Java并发的各种基础工具类,具体主要包括几个方面:

    葆宁

扫码关注云+社区

领取腾讯云代金券