排查GC问题常用的工具(gc overhead limit exceeded 排查)
yuyutoo 2025-07-06 17:44 5 浏览 0 评论
Y说
最近杭州的花都陆陆续续开了。本来打算去太子湾看看郁金香,但到了地方才发现太子湾人满为患,无预约不能进。于是就在西湖边逛了逛,拍了点花花草草的照片。
当然,为了能够拍到好看的照片,我翻出了吃灰已久的索尼微单相机,也顺便学了一波摄影基础,偏入门的摄影知识,整理成了思维导图,包含摄影的理论基础和索尼相机的主要使用方法。感兴趣的朋友可以关注我的微信公众号“编了个程”,回复“摄影基础”就可以获取这份思维导图链接哦。
为什么写这篇文章
作为一个Java程序员,或多或少都了解过JVM和GC算法。但工作中不一定有机会遇到和亲手解决GC问题。
JVM的基础理论、GC排查问题的思路和工具,这部分知识就是平时可能很久都不会用到,但需要用到的时候又非常重要。
而入职面试的时候,经常会有面试官问:有没有排查GC问题的经验?如果这个时候不管你有没有实际排查过GC问题,但能聊一聊排查GC问题的思路,那必然是非常加分的。
最近排查了一个GC问题,于是想整理总结一下与GC有关的知识点,形成系统的知识体系和思维。打算写几篇关于GC的文章。那就从介绍一些GC排查问题的工具说起吧。
在我的个人网站yasinshaw.com上,之前写过一些关于JVM基础的文章。感兴趣的同学可以在“文章”页面搜索“jvm”阅读。
日志和监控
可以在Java程序启动的时候加上一些命令参数,来把程序运行中的GC日志打印出来。
-XX:+PrintGC 输出GC日志
-XX:+PrintGCDetails 输出GC的详细日志
-XX:+PrintGCTimeStamps 输出GC的时间戳(以基准时间的形式)
-XX:+PrintGCDateStamps 输出GC的时间戳(以日期的形式,如 2013-05-04T21:53:59.234+0800)
-XX:+PrintHeapAtGC 在进行GC的前后打印出堆的信息
-Xloggc:../logs/gc.log 日志文件的输出路径
有些命令可能在不同的Java版本适用。比如在Java 11中,就会提示你:-XX:+PrintGC is deprecated. Will use -Xlog:gc instead。
而输出的日志格式,也会根据不同的Java版本和GC有一些细微的差别,这个可以具体根据自己项目上的Java版本和GC去对应具体的格式。
推荐GC日志与logback集成,这样可以利用logback的日志切割功能。
再配上可视化的监控工具和告警工具,就能够及时知道JVM的状态和趋势数据。开源的解决方案推荐的是Prometheus(使用jmx_exporter) + Grafana。
命令行工具
日志和监控更多的是反馈历史的数据和监控告警的作用。而光靠历史的数据有时候并不能很好地定位问题。使用一些命令行工具,可以得到实时的JVM数据。
JDK自带的命令行工具
jps
jps可以查看机器正在运行的Java进程id,虽然用ps -ef | grep java
也能达到类似的效果,但用jps更方便一点。
拿到Java进程id后,可以方便地用下面的命令去获取更多的信息。
jstat
使用jps获得的进程号,可以用jstat实时获取JVM中各区域的信息。
下图是一个Java 8的程序使用jstat打印出来的结果。图中最后两个参数,1000是指的间隔多久采集一次,单位是毫秒。5指的是总共采集次数。
每列的含义:
S0C、S1C、S0U、S1U:Survivor 0/1区容量(Capacity)和使用量(Used)
EC、EU:Eden区容量和使用量
OC、OU:年老代容量和使用量
PC、PU:永久代容量和使用量
YGC、YGT:年轻代GC次数和GC耗时
FGC、FGCT:Full GC次数和Full GC耗时
GCT:GC总耗时
jmap
jmap功能比较强大。它可以生成dump文件,也可以查看堆内对象示例的统计信息、查看ClassLoader的信息以及 finalizer队列,甚至可以远程诊断。
要看JVM的信息很简单,使用jmap -heap 进程号
就可以了。使用jmap也比jstat要更直观一些。
这里有一点坑,就是机器上必须安装了debug包,且版本要与JDK的版本一致(包括小版本),不然会报错。
Arthas
Arthas是一个阿里出品的开源的Java诊断工具,深受开发者喜爱。
使用下面两行命令即可开启Arthas:
curl -O https://arthas.aliyun.com/arthas-demo.jar
java -jar arthas-boot.jar
Arthas有两个主要的命令可以查看JVM信息。一个是dashboard
,另一个是jvm
。
dashboard命令可以查看程序和机器的整体信息。包括主要的线程信息、JVM各区的内存占用情况、Java和操作系统的版本信息等。而且dashboard还可以实时刷新,动态监控。
这里有一个小彩蛋,我们自己创建线程的时候,优先级只能设置为1~10,但JVM自己启动的几个线程(比如编译线程等,优先级可以为-1)。
// Thread类的setPriority方法源码
public final void setPriority(int newPriority) {
ThreadGroup g;
checkAccess();
if (newPriority > MAX_PRIORITY || newPriority < MIN_PRIORITY) {
throw new IllegalArgumentException();
}
if((g = getThreadGroup()) != null) {
if (newPriority > g.getMaxPriority()) {
newPriority = g.getMaxPriority();
}
setPriority0(priority = newPriority);
}
}
而使用jvm
命令,则可以获取更加详细的JVM信息。包括类加载、编译器、GC、内存管理、操作系统、线程等等。
总的来说,我个人觉得arthas比JDK自带的命令行工具好用。信息比较全,而且排版也看起来更方便一些。
dump分析
dump
dump指的是生成快照。在Java中,dump主要要heap dump和thread dump。
Java heap dump可以将当时的JVM信息dump到一个二进制文件,用于后面慢慢分析。可以在Java程序启动的时候,使用参数让程序在指定的时机dump,比如:
-XX:+HeapDumpBeforeFullGC :实现在Full GC前dump。
-XX:+HeapDumpAfterFullGC :实现在Full GC后dump。
-XX:+HeapDumpOnOutOfMemoryError 发生OOM时dump
-XX:+HeapDumpPath :设置Dump保存的路径
也可以使用上面提到的jmap工具来手动dump当前的信息:
jmap -dump:live,file=heap.bin PID
Tips:使用jstack可以进行thread dump,但不在本文范围内,所以不做介绍。
Java自带的Jconsole也有dump功能,可以监控本地或远程的Java进程。它具有图形化的操作界面,还可以实时查看JVM的内存、线程等信息。
分析
JDK自带了一些dump文件分析工具,比如jhat,可以分析dump文件并启动一个http服务器。但jhat已经在Java 9被移除掉。推荐使用Visual VM来分析dump文件,使用Visual VM可以图形化地看到dump时候的对象信息和线程信息。
总结
这些工具都是用来排查GC问题的。在发生GC问题事前,可以通过打日志+监控告警的方式,尽快知道最近一段时间JVM的情况。
在事中,如果不紧急(比如GC变频繁但不影响业务)的情况下,可以使用arthas等命令行工具分析当前的JVM情况。而如果比较紧急(比如Full GC耗时长,影响业务)的情况下,可以使用dump工具把当时的数据dump下来,回滚或限流应用程序,在事后找时间去分析dump文件。
求个支持
我是Yasin,一个坚持技术原创的博主,我的微信公众号是:编了个程
都看到这儿了,如果觉得我的文章写得还行,不妨支持一下。
文章会首发到公众号,阅读体验最佳,欢迎大家关注。
你的每一个转发、关注、点赞、评论都是对我最大的支持!
还有学习资源、和一线互联网公司内推哦
相关推荐
- 全局和隐式 using 指令详解(全局命令)
-
1.什么是全局和隐式using?在.NET6及更高版本中,Microsoft引入了...
- 请停止微服务,做好单体的模块化才是王道:Spring Modulith介绍
-
1、介绍模块化单体是一种架构风格,代码是根据模块的概念构成的。对于许多组织而言,模块化单体可能是一个很好的选择。它有助于保持一定程度的独立性,这有助于我们在需要的时候轻松过渡到微服务架构。Spri...
- ASP.NET程序集引用之痛:版本冲突、依赖地狱等解析与实战
-
我是一位多年后端经验的工程师,其中前几年用ASP.NET...
- .NET AOT 详解(.net 6 aot)
-
简介AOT(Ahead-Of-TimeCompilation)是一种将代码直接编译为机器码的技术,与传统的...
- 一款基于Yii2开发的免费商城系统(一款基于yii2开发的免费商城系统是什么)
-
哈喽,我是老鱼,一名致力于在技术道路上的终身学习者、实践者、分享者!...
- asar归档解包(游戏arc文件解包)
-
要学习Electron逆向,首先要有一个Electron开发的程序的发布的包,这里就以其官方的electron-quick-start作为例子来进行一下逆向的过程。...
- 在PyCharm 中免费集成Amazon CodeWhisperer
-
CodeWhisperer是Amazon发布的一款免费的AI编程辅助小工具,可在你的集成开发环境(IDE)中生成实时单行或全函数代码建议,帮助你快速构建软件。简单来说,AmazonCodeWhi...
- 2014年最优秀JavaScript编辑器大盘点
-
1.WebstormWebStorm是一种轻量级的、功能强大的IDE,为Node.js复杂的客户端开发和服务器端开发提供完美的解决方案。WebStorm的智能代码编辑器支持JavaScript,...
- 基于springboot、tio、oauth2.0前端vuede 超轻量级聊天软件分享
-
项目简介:基于JS的超轻量级聊天软件。前端:vue、iview、electron实现的PC桌面版聊天程序,主要适用于私有云项目内部聊天,企业内部管理通讯等功能,主要通讯协议websocket。支持...
- JetBrains Toolbox推出全新产品订阅授权模式
-
捷克知名软件开发公司JetBrains最为人所熟知的产品是Java编程语言开发撰写时所用的集成开发环境IntelliJIDEA,相信很多开发者都有所了解。而近期自2015年11月2日起,JetBr...
- idea最新激活jetbrains-agent.jar包,亲测有效
-
这里分享一个2019.3.3版本的jetbrains-agent.jar,亲测有效,在网上找了很多都不能使用,终于找到一个可以使用的了,这里分享一下具体激活步骤,此方法适用于Jebrains家所有产品...
- CountDownTimer的理解(countdowntomars)
-
CountDownTimer是android开发常用的计时类,按照注释中的说明使用方法如下:kotlin:object:CountDownTimer(30000,1000){...
- 反射为什么性能会很慢?(反射时为什么会越来越长)
-
1.背景前段时间维护一个5、6年前的项目,项目总是在某些功能使用上不尽人意,性能上总是差一些,仔细过了一下代码发现使用了不少封装好的工具类,工具类里面用了好多的反射,反射会影响到执行效率吗?盲猜了一...
- btrace 开源!基于 Systrace 高性能 Trace 工具
-
介绍btrace(又名RheaTrace)是抖音基础技术团队自研的一款高性能AndroidTrace工具,它基于Systrace实现,并针对Systrace不足之处加以改进,核心改进...
你 发表评论:
欢迎- 一周热门
- 最近发表
-
- .NET 奇葩问题调试经历之3——使用了grpc通讯类库后,内存一直增长......
- 全局和隐式 using 指令详解(全局命令)
- 请停止微服务,做好单体的模块化才是王道:Spring Modulith介绍
- ASP.NET程序集引用之痛:版本冲突、依赖地狱等解析与实战
- .NET AOT 详解(.net 6 aot)
- 一款基于Yii2开发的免费商城系统(一款基于yii2开发的免费商城系统是什么)
- asar归档解包(游戏arc文件解包)
- 在PyCharm 中免费集成Amazon CodeWhisperer
- 2014年最优秀JavaScript编辑器大盘点
- 基于springboot、tio、oauth2.0前端vuede 超轻量级聊天软件分享
- 标签列表
-
- mybatis plus (70)
- scheduledtask (71)
- css滚动条 (60)
- java学生成绩管理系统 (59)
- 结构体数组 (69)
- databasemetadata (64)
- javastatic (68)
- jsp实用教程 (53)
- fontawesome (57)
- widget开发 (57)
- vb net教程 (62)
- hibernate 教程 (63)
- case语句 (57)
- svn连接 (74)
- directoryindex (69)
- session timeout (58)
- textbox换行 (67)
- extension_dir (64)
- linearlayout (58)
- vba高级教程 (75)
- iframe用法 (58)
- sqlparameter (59)
- trim函数 (59)
- flex布局 (63)
- contextloaderlistener (56)