如何通过JVM分析排查问题

大家好,今天我们一起聊聊如何通过JVM分析排查问题。

JVM是我们在做Java开发时,必须要了解和掌握的内容。深入了解JVM,可以在Java开发时,充分考虑JVM的特点,减少YGC或FullGC;深入了解JVM,在我们遇到应用服务瓶颈、卡顿、性能下降时,可以找到排查问题的思路和方法,快速定位问题和解决问题。可以参考往期文章《聊聊程序员需掌握的JVM》《一文掌握线程的状态及转换》,了解一些基础概念。

回顾JVM图和线程状态转换图

JVM相关图:

如何通过JVM分析排查问题

如何通过JVM分析排查问题

线程状态转换的图:

如何通过JVM分析排查问题

TOP命令

top命令是Linux下常用的性能分析工具,它能够实时显示系统中各个进程的资源占用状况,类似于Windows的任务管理器。

top命令提供了一个动态的视图,显示系统当前的进程和其他状态信息。这个视图会不断刷新,用户可以通过交互式命令或按特定的键来刷新状态。如果在前台执行该命令,它将独占前台,直到用户终止该程序为止。

top命令提供了一个实时的对系统处理器的状态监视。它会显示系统中CPU最“敏感”的任务列表,并可以按照CPU使用率、内存使用率和执行时间对任务进行排序。此外,top命令的很多特性都可以通过交互式命令或者在个人定制文件中进行设定。

top命令的参数如下:

  • d:该参数后面可以跟一个数字,表示top命令的刷新间隔。例如,top -d 5将每隔5秒刷新一次显示的信息。

  • -c:以紧凑格式显示进程信息,只显示进程ID、用户、优先级等基本信息。

  • -H:显示线程信息,而不是进程信息。

  • -u:后面跟用户名,只显示指定用户的进程信息。

  • -p:后面跟进程ID,只显示指定进程ID的进程信息。

  • -n:后面跟次数,表示top命令显示的次数。例如,top -n 5将只显示5次进程信息,然后退出。

  • -b:批处理模式,将top命令的输出重定向到一个文件中,通常用于脚本或自动化任务。

  • -o:后面跟一个字段名,按照指定的字段对进程进行排序。例如,top -o %CPU将按照CPU使用率对进程进行排序。

  • -q:后面跟一个数字,表示同时显示的进程数量。例如,top -q 20将只显示前20个进程的信息。

  • -M:以内存单位显示数据,而不是以字节为单位。例如,使用top -M将显示内存使用量以MB为单位。

如何通过JVM分析排查问题

上图中113552为应用服务的pid,可以看到应用对应CPU及内存使用等情况。

如果需要详细查看113552进程编号下,哪些线程占用CPU比较高,可以采用 top -Hp pid的命令:

如何通过JVM分析排查问题

上图的pid为线程编号,需要转换为16进制,可以通过windows计算器转,或者使用linux命令 printf “%xn” 113633

如何通过JVM分析排查问题

jstack获取线程栈信息

jstack是JVM自带的Java堆栈跟踪工具,用于打印给定Java进程ID、core file或远程调试服务的Java堆栈信息。

jstack命令的输出主要包括JVM自身线程和用户线程的信息,其中JVM线程会在JVM启动时存在,而用户线程则是在用户访问时生成。通过jstack输出的线程信息,可以定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致的长时间等待等问题。

jstack有以下参数
  • -F:如果正常执行jstack命令没有响应(比如进程hung住了),可以加上此参数强制执行thread dump。

  • -m:除了打印Java的方法调用栈之外,还会输出native方法的栈帧。

  • -l:打印与锁有关的附加信息。使用此参数会导致JVM停止时间变长,在生产环境需慎用。

查看该线程对应的栈情况,将上面的结果1bbe1前面加0x,即0x1bbe1,命令:jstack 113633 | grep 0x1bbe1 -A30

如何通过JVM分析排查问题

消耗CPU比较高的线程的栈信息,可以通过以上命令,查看是否为代码层的原因引起的CPU冲高,留意是否存在dead lock(死锁)的状态,针对TIMED_WAITING / WAITING / BLOCKED 状态分析,是否存在不必要的锁等待等。需要注意的是,若占用CPU较高的线程运行的时间比较久,可以通过以上的方式抓到线程对应的栈信息,若该线程占用CPU的时间比较短或者很短的时间已运行结束,通过以上方式,无法抓到需要的信息,可以采用脚本一体化运行的方式抓信息,并保存以备排查分析。

jmap获取进程堆信息

jmap是一个用于查看JVM内存使用情况的命令。jmap命令有以下参数:

  • -histo:显示堆内存的直方图,包括每个类的实例数、所占空间大小及类名。

  • -histo:live:观察堆中所有生存的对象,包括对象数量和所占空间大小,并将结果输出到文件中。可以用于后续分析。

有时,在存在对象锁或对象等待等,需要详细排查对象信息时,可以通过jmap -heap 的方式,获取堆的信息,并通过MAT工具详细分析堆的具体情况。

如何通过JVM分析排查问题

如何通过JVM分析排查问题

jstat的JVM命令

jstat是一个用于监视JVM统计信息的命令行工具。

jstat通用参数:

  • -options:显示输出选项的列表。

  • -help:显示帮助信息。

  • -class:显示类加载器统计信息。

  • -compiler:显示即时编译方法的统计信息。

  • -gc:显示垃圾收集统计信息,包括堆内存使用情况、垃圾收集次数和时间等。

  • -gccapacity:显示各个代的大小和最大可用内存。

  • -gccause:显示垃圾收集统计信息和导致停止的原因。

  • -gcnew:显示新生代垃圾收集统计信息。

  • -gcnewcapacity:显示新生代的大小和最大可用内存。

  • -gcold:显示老年代垃圾收集统计信息。

  • -gcoldcapacity:显示老年代的大小和最大可用内存。

  • -printcompilation:打印已编译方法的信息。

时间间隔和计数器选项:

  • interval:显示信息的时间间隔,单位为毫秒或秒。默认值为1000毫秒。

  • count:查询次数,如果省略该参数则无限循环输出直到被中断。默认值为10次。

使用jstat命令时,需要指定一个或多个参数来查询特定的JVM统计信息。例如,要监视垃圾收集的统计信息,可以使用以下命令:jstat -gcutil <pid> <interval> <count>。其中<pid>是要监视的Java进程的进程ID,<interval>是查询的时间间隔,<count>是查询的次数。如果省略<count>参数,则默认查询无限次数直到被中断。jstat命令的输出将包括堆内存使用情况、垃圾收集次数和时间等统计信息,这些信息对于分析和调优JVM性能非常有用。

jstat -options:

如何通过JVM分析排查问题

jstat -gc pid:

如何通过JVM分析排查问题

jstat -gcutil pid periodMills:

如何通过JVM分析排查问题

总结

通过有效的命令组合,可以分析出JVM的gc情况和指标(jstat),可以分析出应用占用的CPU及内存指标(top ),可以分析出应用占用CPU高的线程信息(top -Hp pid),可以找出对应线程的栈信息(jstack pid | grep 线程地址nid),可以生成进程的堆信息文件(jmap)。根据各项指标及获取到的堆栈信息,可以排查应用层的问题点。通过JVM的gc情况,可以分析内存参数配置是否合理,是否需要调整等。当然,影响应用性能的原因还有很多,如CPU及磁盘IO的资源等,需结合起来一起分析。

原文始发于微信公众号(扬哥手记):如何通过JVM分析排查问题

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/239557.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!