百度360必应搜狗淘宝本站头条
当前位置:网站首页 > IT技术 > 正文

排查GC问题常用的工具_排查gc问题常用的工具有

wptr33 2025-02-19 14:09 17 浏览

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,一个坚持技术原创的博主,我的微信公众号是:编了个程

都看到这儿了,如果觉得我的文章写得还行,不妨支持一下。

文章会首发到公众号,阅读体验最佳,欢迎大家关注。

你的每一个转发、关注、点赞、评论都是对我最大的支持!

还有学习资源、和一线互联网公司内推哦

相关推荐

Linux文件系统操作常用命令(linux文件内容操作命令)

在Linux系统中,有一些常用的文件系统操作命令,以下是这些命令的介绍和作用:#切换目录,其中./代表当前目录,../代表上一级目录cd#查看当前目录里的文件和文件夹ls#...

别小看tail 命令,它难倒了技术总监

我把自己以往的文章汇总成为了Github,欢迎各位大佬star...

lnav:基于 Linux 的高级控制台日志文件查看器

lnav是一款开源的控制台日志文件查看器,专为Linux和Unix-like系统设计。它通过自动检测日志文件的格式,提取时间戳、日志级别等关键信息,并将多个日志文件的内容按时间顺序合并显示,...

声明式与命令式代码(声明模式和命令模式)

编程范式中的术语和差异信不信由你,你可能已经以开发人员的身份使用了多种编程范例。因为没有什么比用编程理论招待朋友更有趣的了,所以这篇文章可以帮助您认识代码中的流行范例。命令式编程命令式编程是我们从As...

linux中的常用命令(linux常用命令和作用)

linux中的常用命令linux中的命令统称shell命令shell是一个命令行解释器,将用户命令解析为操作系统所能理解的指令,实现用户与操作系统的交互shell终端:我们平时输入命令,执行程序的那个...

提高工作效率的--Linux常用命令,能够决解95%以上的问题

点击上方关注,第一时间接受干货转发,点赞,收藏,不如一次关注评论区第一条注意查看回复:Linux命令获取linux常用命令大全pdf+Linux命令行大全pdf...

如何限制他人操作自己的电脑?(如何控制别人的电脑不让发现)

这段时间,小猪罗志祥正处于风口浪尖,具体是为啥?还不知道的小伙伴赶紧去补一下最近的娱乐圈八卦~简单来说,就是我们的小罗同事,以自己超强的体力,以及超强的时间管理能力,重新定义了「多人运动」的含义,重新...

最通俗易懂的命令模式讲解(命令模式百科)

我们先不讲什么是命令模式,先通过一个场景来引出命令模式,看看命令模式能解决什么样的问题。现在有一个渣男张三,他有还几个女朋友,你现在是不是还是单身狗,你就说你气不气?然后他需要每天分别叫几个女朋友起床...

互联网大厂后端必看!Spring Boot 中Runtime执行与停止命令?

你是否曾在使用SpringBoot开发项目时,遇到需要执行系统命令的场景?比如调用脚本进行文件处理,又或是启动外部程序?很多后端开发人员会使用Processexec=Runtime.get...

Linux 常用命令(linux常用的20个命令面试)

日志排查类操作命令...

Java字节码指令:if_icmpgt(0xA3)(java字节码使用的汇编语言)

if_icmpgt是Java字节码中的一条条件跳转指令,其全称是"IfIntegerCompareGreaterThan"。它用于比较两个整数值的大小。如果栈顶的第一个...

外贸干货|如何增加领英的曝光量和询盘

#跨境电商#...

golang执行linux命令(golang调用shell脚本)

需求需要通过openssl生成rsa秘钥,然后保存该秘钥。代码实例packagemainimport("io/ioutil""bytes"&...

LINUX磁盘挂载(linux磁盘挂载到windows)

1、使用root用户查看磁盘挂载情况:fdisk-l2、使用df查看当前磁盘挂载情况,根据和fdisk-l的结果进行对比,查看还有那些磁盘未使用3、挂载:mount磁盘挂载路径...

Linux命令学习——nl命令(linux ln命令的使用)

nl命令主要功能为每一个文件添加行号,每一个输入的文件添加行号后发送到标准输出。当没有文件或文件为-时,读取标准输入...