JVM gc日志分析

一、常用gc日志配置参数

-XX:+PrintGC #输出GC日志
-XX:+PrintGCDetails #输出GC的详细日志
-XX:+PrintGCTimeStamps #输出GC的时间戳(代表了GC发生的时间,这个数字的含义是从Java
虚拟机启动以来经过的秒数)
-XX:+PrintGCDateStamps #输出GC的时间戳(以日期的形式,如 2013-05-04T21:53:59.234+0800)
-XX:+PrintHeapAtGC #在进行GC的前后打印出堆的信息
-XX:+PrintTenuringDistribution  #输出显示在survivor空间里面有效的对象的岁数情况
-XX:+UseGCLogFileRotation  #使用日志文件旋转
-XX:NumberOfGCLogFiles=12  #日志文件数量
-XX:GCLogFileSize=128M  #日志文件大小

-Xloggc:../logs/gc.log  #日志文件的输出路径

二、gc日志含义分析

配置

-XX:+PrintGCDetails -XX:+PrintGCDateStamps  -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=12 -XX:GCLogFileSize=128M -Xloggc:logs/gc-flume.log

日志

2018-04-28T11:04:12.391+0800: 64.264: [GC [PSYoungGen: 85440K->3488K(89600K)] 147397K->69117K(164352K), 0.0052610 secs] [Times: user=0.01 sys=0.00, real=0.00 secs]
2018-04-28T11:04:14.774+0800: 66.647: [GC [PSYoungGen: 85408K->3604K(105984K)] 151037K->72914K(180736K), 0.0040650 secs] [Times: user=0.01 sys=0.00, real=0.01 secs] 
2018-04-28T11:04:14.778+0800: 66.651: [Full GC [PSYoungGen: 3604K->0K(105984K)] [ParOldGen: 69309K->28865K(77312K)] 72914K->28865K(183296K) [PSPermGen: 12750K->12750K(27648K)], 0.0468910 secs] [Times: user=0.11 sys=0.00, real=0.04 secs] 

第三条Full gc为例

1.GC日志开头的“[GC”和“[Full GC”说明了这次垃圾收集的停顿类型,如果有“Full”,说明这次GC是发生了Stop-The-World,如下几种情况下会发生full gc:

1.System.gc()方法的调用,可通过DisableExplicitGC来禁止
2.老年代空间不足
3.永生区空间不足
4.CMS GC时出现promotion failed和concurrent mode failure
5.统计得到的Minor GC晋升到旧生代的平均大小大于老年代的剩余空间
6.堆中分配很大的对象
6.存在rmi调用时,默认会每分钟执行一次System.gc,可以通过-Dsun.rmi.dgc.server.gcInterval=3600000来设置大点的间隔。

详见:https://blog.csdn.net/chenleixing/article/details/46706039

2.PSYoungGen表示GC发生的区域,PSYoungGen表示新生代采用Parallel Scavenge收集器。使用Serial收集器新生代名称为DefNew,使用ParNew收集器名称为ParNew

3.后面方括号内部含义是“GC前该内存区域已使用容量->GC后该内存区域已使用容量(该内存区域总容量)”。PSYoungGen: 3604K->0K(105984K)代表新生代内存回收情况,[ParOldGen: 69309K->28865K(77312K)代表老年代内存回收情况,而在方括号之外的“172914K->28865K(183296K)”表示“GC前Java堆已使用容量->GC后Java堆已使用容量(Java堆总容量)”,[PSPermGen: 12750K->12750K(27648K)]代表永久代内存回收情况。

4.再往后,“0.0052610 secs”表示该内存区域GC所占用的时间,单位是秒

5.[Times: user=0.01 sys=0.00, real=0.00 secs] ;这里面的user、sys和real与Linux的time命令所输出的时间含义一致,分别代表用户态消耗的CPU时间、 内核态消耗的CPU事件和操作从开始到结束所经过的墙钟时间(Wall Clock Time)。 CPU时间与墙钟时间的区别是,墙钟时间包括各种非运算的等待耗时,例如等待磁盘I/O、 等待线程阻塞,而CPU时间不包括这些耗时,但当系统有多CPU或者多核的话,多线程操作会叠加这些CPU时间,所以读者看到user或sys时间超过real时间是完全正常的。

我们再对数据做一个简单的分析

从第二次GC记录中我们可以看到 Young GC回收了 85408K->3604K=81804K的内存
Heap区通过这次回收总共减少了 151037K->72914K=78123K的内存。
81804K-78123K=3681K说明通过该次Young GC有3681K的内存被移动到了Old Gen

我们来验证一下
在第一次Young GC 的Old Gen的大小为69117-3488=65629K
第二次Young GC 的Old Gen的大小72914-3604=69310K
Old Gen在第二次Young GC以后内存增加了69310-65629=3681K 与预计的相符

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
您好!对于JVM(Java虚拟机)在进行Full GC(垃圾回收)后无法重启的情况,可能有多种原因导致。以下是一些常见的可能原因和解决方法: 1. 内存设置不当:Full GC 可能由于内存不足而导致无法重启。您可以尝试增加JVM的内存限制(通过调整-Xmx和-Xms参数)来解决该问题。 2. 系统资源不足:Full GC 执行期间,系统资源(如CPU、磁盘空间等)可能出现瓶颈,导致无法重启。您可以检查系统资源使用情况,并进行相应的优化或增加资源。 3. 线程死锁:Full GC 可能会暂停应用程序的所有线程,如果存在线程死锁,可能导致无法恢复。您可以使用线程转储工具(如jstack)来检查是否存在线程死锁,并解决死锁问题。 4. 第三方库或框架问题:某些第三方库或框架可能存在与Full GC 不兼容的问题,导致无法重启。您可以尝试更新相关库或框架版本,或者联系供应商以获取支持。 5. JVM Bug:在某些情况下,Full GC 无法重启的问题可能是由于JVM本身的Bug引起的。您可以尝试更新JVM版本,或者向JVM的开发者报告该问题以获取解决方案。 请注意,以上只是一些可能的原因和解决方法,具体情况需要根据实际环境和日志信息进行分析和判断。如果问题仍然存在,请尝试记录相关错误信息并查看相应的日志文件,这有助于更好地定位和解决问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值