通过JVM日志查看GC情况

原文出处:plumbr.eu

许多事件都可能会导致JVM暂停所有的应用线程。这类暂停又被称为”stop-the-world”(STW)暂停。触发STW暂停最常见的原因就是垃圾回收了(github中的一个例子),但不同的JIT活动(例子),偏向锁擦除(例子),特定的JVMTI操作,以及许多场景也可能会导致应用程序暂停。

应用程序线程可以被安全地停止掉的那个时间点,就叫做安全点。这一术语也通常用来指代SWT暂停。

通常来讲GC日志都是打开的。然而,并非所有安全点的信息都能完整地记录下来。想获取到完整的日志,可以使用下列的JVM选项:

-XX:+PrintGCApplicationStoppedTime -XX:+PrintGCApplicationConcurrentTime

从参数名字来看你可能会觉得是与GC相关的,其实不然——打开这些选项能够记录下所有的安全点,而不止是GC暂停的。如果你用上述的选项来运行下这个例子(github源码

你会在标准输出中看到如下信息:

Application time: 0.3440086 seconds
Total time for which application threads were stopped: 0.0620105 seconds
Application time: 0.2100691 seconds
Total time for which application threads were stopped: 0.0890223 seconds

很通俗易懂(和GC日志相比来说)——从中你可以得知应用程序在前344毫秒中是在处理实际工作的,然后将所有线程暂停了62毫秒,紧接着又工作了210ms,然后又暂停了89ms。

你还可以将这些选项与GC的选项结合起来使用,比如将上面这个程序加上-XX:+PrintGCDetails 选项后再运行一次,输出则变成这样了;

[Full GC (Ergonomics) [PSYoungGen: 1375253K->0K(1387008K)] [ParOldGen: 2796146K->2049K(1784832K)] 4171400K->2049K(3171840K), [Metaspace: 3134K->3134K(1056768K)], 0.0571841 secs] [Times: user=0.02 sys=0.04, real=0.06 secs]

Total time for which application threads were stopped: 0.0572646 seconds, Stopping threads took: 0.0000088 seconds

综上可知,应用线程被强制暂停了57ms来进行垃圾回收。其中又有8ms是用来等待所有的应用线程都到达安全点。如果我们用同样的选项运行另一个例子(Github源码)的话,输出又变成这样的了:

Total time for which application threads were stopped: 0.0001273 seconds, Stopping threads took: 0.0000196 seconds

Total time for which application threads were stopped: 0.0000648 seconds, Stopping threads took: 0.0000174 seconds

光从这些信息我们无从得知是什么导致的暂停,因为看不出有任何的垃圾回收的活动。如果你想更详细地了解安全点的信息的话,可以使用这组JVM参数:

-XX:+PrintSafepointStatistics -XX:PrintSafepointStatisticsCount=1

启用这些参数使得JVM会将一些额外的信息记录到标准输出中,大概类似这样:

1

2

5.141``: RevokeBias?????????????????????? [????? 13 0 2 ]????? [???? 0 0 0 0 0 ]? 0

Total time for which application threads were stopped: 0.0000782 seconds, Stopping threads took: 0.0000269 seconds

关于安全点的信息是按照如下的顺序进行显示的:

  • JVM启动之后所经历的毫秒数(上例中是5.141)
  • 触发这次暂停的操作名(RevokeBias)。 如果你看见”no vm operation”,就说明这是一个”保证安全点”。JVM默认每秒会触发一次安全点来处理那些非紧急的排队的操作。GuaranteedSafepointInterval选项可以用来调整这一行为(设置为0的话就会禁用该功能)
  • 停在安全点的线程的数量(13)
  • 在安全点开始时仍在运行的线程的数量(0)
  • 虚拟机操作开始执行前仍处于阻塞状态的线程的数量(2)
  • 到达安全点时的各个阶段以及执行操作所花的时间(0)

因此我们可以看出,使用了偏向锁会导致大量的STW暂停,尽管它们只花了几十毫秒。在如今这个大量使用并发的年代,禁用它们也不是什么罕见的事情。

不管怎样,多打印些日志总会减少一些麻烦事的。你可以使用如下的JVM参数:

-XX:+LogVMOutput -XX:LogFile=vm.log

所有的虚拟机日志都会输出到vm.log文件中。如何解读这些日志并做出响应是一个很大的课题,这已经远超本文所讨论的范围了,不过未来我仍会更新一到两篇文章来讲下这个,请拭目以待.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 您可以通过以下步骤查看 JVM Full GC 的具体原因: 1. 首先,您需要在 JVM 启动时添加以下参数:-XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -Xloggc:<log_file_path> 2. 然后,您需要分析生成的 GC 日志文件,查找 Full GC 的记录。 3. 在 Full GC 记录中,您可以查看以下信息: - Full GC 发生的原因,例如内存不足、永久代满、CMS GC 失败等。 - Full GC 前后堆内存的使用情况,以及 GC 前后各代内存的使用情况。 - Full GC 所花费的时间,以及 Full GC 后堆内存的使用情况。 通过分析这些信息,您可以确定 Full GC 的具体原因,并采取相应的措施来优化应用程序的性能。 ### 回答2: 查看JVM Full GC的具体原因可以通过以下步骤进行: 1. 监控工具:使用一些常见的JVM性能监控工具,如JConsole、VisualVM、Java Mission Control等。这些工具可以提供实时的JVM运行信息,其中包含Full GC的相关指标和堆内存的使用情况。 2. 日志分析:查看应用程序的日志文件,搜索其中包含GC的相关日志。根据GC日志中的时间戳、GC类型和相关指标(如堆内存的使用情况、对象生命周期等),可以进一步分析Full GC的原因。 3. 分析GC日志:当JVMGC日志被启用时,可以通过分析GC日志来了解Full GC的具体原因。GC日志中会记录GC活动的详细信息,包括GC类型、GC时间、GC前后堆内存的使用情况等。 4. 堆内存分析工具:使用一些堆内存分析工具,如Eclipse Memory Analyzer Tool(MAT),通过导入堆转储快照文件,可以分析堆内存中的对象分布、对象引用关系等,从而找出可能导致Full GC的原因。例如,一些内存泄漏或者大对象的创建可能导致堆内存不足,进而引发Full GC的发生。 5. JVM参数调整:根据分析结果,如果是堆内存不足导致Full GC的话,可以考虑调整JVM的相关参数,如-Xmx(最大堆大小)、-Xms(初始堆大小)等,增加堆内存的分配。 综上所述,通过使用监控工具、分析GC日志、堆内存分析工具以及调整JVM参数等方法,可以查看JVM Full GC的具体原因。 ### 回答3: 要查看JVM Full GC的具体原因,可以按照以下步骤进行: 1. 设置JVM日志级别:在启动JVM时,使用-XX:+PrintGCDetails或-XX:+PrintGCTimeStamps等参数,将JVMGC日志级别设置为详细模式。这样可以确保在日志中记录Full GC事件的详细信息。 2. 分析GC日志:定期检查和分析JVMGC日志。在GC日志中,Full GC事件通常以“Full GC”或“Full GC(System)”的形式出现。同时会显示一些关键信息,如Full GC消耗的时间、GC前后堆内存的情况等。 3. 查看GC原因:在GC日志中,找到Full GC事件的触发原因。可能的原因包括年轻代或老年代空间不足、永久代空间不足、老年代对象引用链过长等。根据Full GC事件的触发原因,可以进一步分析和解决问题。 4. 使用工具进行分析:可以使用一些专门的工具来分析GC日志,如GCViewer、GCMV等。这些工具可以图形化地展示GC事件的情况,包括GC发生的次数、GC消耗的时间、堆内存的变化等。通过这些工具,可以更直观地查看和分析Full GC的具体原因。 5. 进行性能调优:根据Full GC的具体原因,进行相应的性能调优操作。例如,如果是堆内存不足导致的Full GC,可以通过增加堆内存大小来解决问题;如果是对象引用链过长导致的Full GC,可以优化代码,减少对象间的引用链长度等。 通过以上方法,可以查看JVM Full GC的具体原因,并根据需要进行相应的优化和调整,以提高系统性能和稳定性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值