专业的编程技术博客社区

网站首页 > 博客文章 正文

JVM内存飙升,我们该如何排查?

baijin 2025-05-14 11:52:54 博客文章 4 ℃ 0 评论

首先这个问题是自己的一个亲身项目经历,具体是这样的..................

在一个月黑风高的夜里,刚刚爬上**的床,准备大干一番。。。事业,这时手机不停收到告警,赶紧从忙碌中停了下来.

短信告警内容大概是服务器CPU占用90%以上,反正是飙升,二话不说,感觉打开电脑VPN远程看下;根据流量判断肯定不是用户请求增多导致,于是想到今天有发版,会不会代码引起的异常;于是先看下CPU飙高到底是那些进程引起;步骤如下:

说明:截图是已经解决问题之后的,所以显示数值都是正常范围

1.执行top命令

通过此命令可看到java进程的PID,但是真正占用情况我们需要查看线程的具体情况

2.执行top -Hp pid

这个可以看到具体线程的指标情况,但是对于排查问题这是不够,我们需要查看堆栈的使用情况,具体方法比较多,举常用说明:

2.1JDK工具之jstat命令

jstat可以监测Java应用程序的实时运行情况,包括堆内存信息以及垃圾回收信息。我们可以运行jstat -help查看一些关键参数信息:

再通过jstat -option查看jstat有哪些操作:

  • -class:显示ClassLoad的相关信息;
  • -compiler:显示JIT编译的相关信息;
  • -gc:显示和gc相关的堆信息;
  • -gccapacity:显示各个代的容量以及使用情况;
  • -gcmetacapacity:显示Metaspace的大小;
  • -gcnew:显示新生代信息;
  • -gcnewcapacity:显示新生代大小和使用情况;
  • -gcold:显示老年代和永久代的信息;
  • -gcoldcapacity :显示老年代的大小;
  • -gcutil:显示垃圾收集信息;
  • -gccause:显示垃圾回收的相关信息(通-gcutil),同时显示最后一次或当前正在发生的垃圾回收的诱因;
  • -printcompilation:输出JIT编译的方法信息。

我们可以用jstat -gc pid查看:


  • S0C:年轻代中To Survivor的容量(单位KB);
  • S1C:年轻代中From Survivor的容量(单位KB);
  • S0U:年轻代中To Survivor目前已使用空间(单位KB);
  • S1U:年轻代中From Survivor目前已使用空间(单位KB);
  • EC:年轻代中Eden的容量(单位KB);
  • EU:年轻代中Eden目前已使用空间(单位KB);
  • OC:Old代的容量(单位KB);
  • OU:Old代目前已使用空间(单位KB);
  • MC:Metaspace的容量(单位KB);
  • MU:Metaspace目前已使用空间(单位KB);
  • YGC:从应用程序启动到采样时年轻代中gc次数;
  • YGCT:从应用程序启动到采样时年轻代中gc所用时间(s);
  • FGC:从应用程序启动到采样时old代(全gc)gc次数;
  • FGCT:从应用程序启动到采样时old代(全gc)gc所用时间(s);
  • GCT:从应用程序启动到采样时gc用的总时间(s)。

  • 2.2JDK工具之jstack命令

    它是一种线程堆栈分析工具,最常用的功能就是使用 jstack pid 命令查看线程的堆栈信息,通常会结合top -Hp pid 或 pidstat -p pid -t一起查看具体线程的状态,也经常用来排查一些死锁的异常。

    每个线程堆栈的信息中,都可以查看到线程ID、线程的状态(wait、sleep、running 等状态)以及是否持有锁等。


    2.3 JDK工具之jmap命令

    在第23讲中我们使用过jmap查看堆内存初始化配置信息以及堆内存的使用情况。那么除了这个功能,我们其实还可以使用jmap输出堆内存中的对象信息,包括产生了哪些对象,对象数量多少等。

    我们可以用jmap来查看堆内存初始化配置信息以及堆内存的使用情况:


    我们可以使用jmap -histo[:live] pid查看堆内存中的对象数目、大小统计直方图,如果带上live则只统计活对象:

    我们可以通过jmap命令把堆内存的使用情况dump到文件中:

    本文暂时没有评论,来添加一个吧(●'◡'●)

    欢迎 发表评论:

    最近发表
    标签列表