• 【Java】java | jvm | 分析cpu占用过高 | 分析jvm堆栈信息


    一、说明

            1、正式环境,cpu飙升,需要排查想原因

            2、正式环境: CentOS8 + jdk8 + nginx + java服务

    二、过程

    1、查看cpu占用

    1)命令

    top c

    说明1: 从高到低,显示cpu占用,并标识应用

    ~~

    2、查看pid的子线程

    1)命令

    top -Hp ${pid}

    说明: 查询的子线程,即tid,线程ID

    ~~

     3、将tid转为16进制

    1)命令

    printf "%x \n" ${tid}

    说明: 后续命令要用到

    4、打印堆栈信息

    1)命令

    jstack ${pid} | grep ${16进制tip} -A 30

    说明1: pid是程序id;tid是线程id(16进制的)

    说明2: -A 30,即打印30行;也可以改成300

    说明3: jstack如果找不到的话,使用绝对路径,在$JAVA_HOME/bin

    说明4: 可以打印处理

    echo $JAVA_HOME

    示例:

    /opt/jdk/jdk1.8.0_231/bin/jstack 584867 | grep 8ed00 -A 30

    说明5:一般把结果导入到文件,然后下载到windows环境查看

    /opt/jdk/jdk1.8.0_231/bin/jstack 584867 | grep 8ed00 -A 30 > jstack.log

    说明6: 下载并查看排查就不赘述了

    ~~

    5、备份其他命令

    1)jmap -heap ${pid}:输出堆内存设置和使用情况(JDK11使用jhsdb jmap --heap --pid pid)

    jmap -heap 

    2)jinfo -flags ${pid}:查看运行时进程参数与JVM参数

    /opt/jdk/jdk1.8.0_231/bin/jinfo -flags 

    3)jmap -histo ${pid}:输出heap的直方图,包括类名,对象数量,对象占用大小

    jmap -histo 

    说明: 建议用绝对路径,当系统装了多个jdk版本的话,可能提示版本不一致的问题

    4)查看系统支持的最大线程数

    cat /proc/sys/kernel/threads-max

    5)jvm系统监控软件

    jvisualvm

    下载链接

    https://visualvm.github.io/index.html

    ~~

    6、cpu飙升原因分析

    1)事情的经过

    a> 项目是老项目(springboot),是war包,用的tomcat独立容器,版本是: apache-tomcat-8.5.64;什么问题呢,分析得出结论是连接没有释放,tomcat连接线程处于WAITING状态(假死),导致cpu居高不下,重启后恢复

    b> 改了项目配置,用springboot内嵌tomcat,版本是: 9.0.39,然后还是发现cpu居高不下,找了好多blog,有个文章说是资源泄露了、建议用线程池,就往这个方向靠;然后全局搜了tomcat配置,确定下是否用了线程池;然后发现,没有用到;然后yml增加上配置

    1. tomcat:
    2. # tomcat的URI编码
    3. uri-encoding: UTF-8
    4. # 连接数满后的排队数,默认为100
    5. accept-count: 5000
    6. threads:
    7. # tomcat最大线程数,默认为200
    8. max: 5000
    9. # Tomcat启动初始化的线程数,默认值10
    10. min-spare: 100

    重启后,cpu降下来了,低于40%(姑且认定为配置有效)

    c> 但是,监控了一段时间,发现cpu还会飙到40%;执行了上面的堆栈信息,WAITING已经没有了,改成了这个:

     没有看错,是业务代码,业务代码导致cpu飙升,可以断定是这块业务有计算量。

    d> 看了业务代码,这块用到一个算法;然后加了些日志,打印下耗时时间。结果发现,的确是算法涉及到计算(计算参数越多、越耗时,目前发现一次计算最大耗时2分钟)。算法计算这块,不属于服务异常了,但是依然是个潜在的风险点,还需要想办法规避掉;要么改算法,要么扩容cpu(4核的,的确不够看),要么用其他方案。

    e>  大致上是这么个情况。

    ~~

  • 相关阅读:
    spark—算子详解
    git 相关命令
    深度学习中的一些概念
    spring容器ioc和di
    如何将dwg文件转成kml文件
    【数据结构】List、Set、Map的联系和区别(通俗易懂,清晰直观!!)
    【Nginx33】Nginx学习:重写更改请求模块
    22071驱动day1
    edge浏览器被恶意插件劫持,不能删除由组织安装的扩展,提示您的浏览器由您的组织管理
    码农必备,一款超好用Json编辑工具
  • 原文地址:https://blog.csdn.net/myloverisxin/article/details/126491238