Gc日志解析
2016-01-20 17:29
323 查看
—–java的最大好处是自动垃圾回收,这样就无需我们手动的释放对象空间了,但是也产生了相应的负效果,gc是需要时间和资源的,不好的gc会严重影响系统的系能,因此良好的gc是JVM的高性能的保证。JVM堆分为新生代,旧生代和年老代,新生代可用的gc方式有:串行gc(Serial Copying),并行回收gc(Parellel Scavenge),并行gc(ParNew),旧生代和年老代可用的gc方式有串行gc(Serial MSC),并行gc(Parallel MSC),并发gc(CMS)。
client模式下,新生代选择的是串行gc,旧生代选择的是串行gc
server模式下,新生代选择的是并行回收gc,旧生代选择的是并行gc
一般来说我们系统应用选择有两种方式:吞吐量优先和暂停时间优先,对于吞吐量优先的采用server默认的并行gc方式,对于暂停时间优先的选用并发gc(CMS)方式。
CMS并非没有暂停,而是用两次短暂停来替代串行标记整理算法的长暂停,它的收集周期是这样:
初始标记(CMS-initial-mark) -> 并发标记(CMS-concurrent-mark) -> 重新标记(CMS-remark) -> 并发清除(CMS-concurrent-sweep) ->并发重设状态等待下次CMS的触发(CMS-concurrent-reset)。
其中的1,3两个步骤需要暂停所有的应用程序线程的。第一次暂停从root对象开始标记存活的对象,这个阶段称为初始标记;第二次暂停是在并发标记之后,暂停所有应用程序线程,重新标记并发标记阶段遗漏的对象(在并发标记阶段结束后对象状态的更新导致)。第一次暂停会比较短,第二次暂停通常会比较长,并且 remark这个阶段可以并行标记。
而并发标记、并发清除、并发重设阶段的所谓并发,是指一个或者多个垃圾回收线程和应用程序线程并发地运行,垃圾回收线程不会暂停应用程序的执行,如果你有多于一个处理器,那么并发收集线程将与应用线程在不同的处理器上运行,显然,这样的开销就是会降低应用的吞吐量。Remark阶段的并行,是指暂停了所有应用程序后,启动一定数目的垃圾回收进程进行并行标记,此时的应用线程是暂停的。
如下几种情况下会发生full gc:
旧生代空间不足
持久代空间不足
CMS GC时出现了promotion failed和concurrent mode failure
统计得到新生代minor gc时晋升到旧生代的平均大小小于旧生代剩余空间
直接调用System.gc,可以DisableExplicitGC来禁止
存在rmi调用时,默认会每分钟执行一次System.gc,可以通过
Dsun.rmi.dgc.server.gcInterval=3600000来设置大点的间隔
日志分析图
description
Full GC:垃圾回收的停顿类型
3654.523:虚拟机启动以来的秒数
oldGenBefore->oldGenAfter(oldGenTotal),oldGenTimeConsuming
CMS: CMS,全称Concurrent Low Pause Collector,是jdk1.4后期版本开始引入的新gc算法,在jdk5和jdk6中得到了进一步改进,它的主要适合场景是对响应时间的重要性需求大于对吞吐量的要求,能够承受垃圾回收线程和应用线程共享处理器资源,并且应用中存在比较多的长生命周期的对象的应用。CMS是用于对tenured generation的回收,也就是年老代的回收,目标是尽量减少应用的暂停时间,减少full gc发生的几率,利用和应用程序线程并发的垃圾回收线程来标记清除年老代.
oldGenBefore: gc前old区内存占用
oldGenAfter: gc后old区内存占用
oldGenTotal: old区内存总大小
heapBefore-heapAfter(heapTotal)
heapBefore: gc前堆内存大小
heapAfter: gc后堆内存大小
heapTotal: jvm堆内存总大小
metaspaceBefore->metaspaceAfter(metaspaceTotal)
Metaspace: 永久保存区
metspaceBefore: gc前堆内存大小
metaspaceAfter: gc后堆内存大小
metaspaceTotal: 永久保存区总大小
fullGCTimeConsuming
gc耗时
userTimeCo
4000
nsuming->sysTimeConsuming->realTimeConsuming
用户态消耗的CPU时间(用户时间)
内核态消耗的CPU时间(系统时间)
操作从开始到结束所经过的墙钟时间(实际时间)
To reader: 所述如有不妥之处,还望不吝指正~
回收方式的选择
jvm有client和server两种模式,这两种模式的gc默认方式是不同的:client模式下,新生代选择的是串行gc,旧生代选择的是串行gc
server模式下,新生代选择的是并行回收gc,旧生代选择的是并行gc
一般来说我们系统应用选择有两种方式:吞吐量优先和暂停时间优先,对于吞吐量优先的采用server默认的并行gc方式,对于暂停时间优先的选用并发gc(CMS)方式。
CMS Gc
CMS,全称Concurrent Low Pause Collector,是jdk1.4后期版本开始引入的新gc算法,在jdk5和jdk6中得到了进一步改进,它的主要适合场景是对响应时间的重要性需求大于对吞吐量的要求,能够承受垃圾回收线程和应用线程共享处理器资源,并且应用中存在比较多的长生命周期的对象的应用。CMS是用于对tenured generation的回收,也就是年老代的回收,目标是尽量减少应用的暂停时间,减少full gc发生的几率,利用和应用程序线程并发的垃圾回收线程来标记清除年老代。在我们的应用中,因为有缓存的存在,并且对于响应时间也有比较高的要求,因此希望能尝试使用CMS来替代默认的server型JVM使用的并行收集器,以便获得更短的垃圾回收的暂停时间,提高程序的响应性。CMS并非没有暂停,而是用两次短暂停来替代串行标记整理算法的长暂停,它的收集周期是这样:
初始标记(CMS-initial-mark) -> 并发标记(CMS-concurrent-mark) -> 重新标记(CMS-remark) -> 并发清除(CMS-concurrent-sweep) ->并发重设状态等待下次CMS的触发(CMS-concurrent-reset)。
其中的1,3两个步骤需要暂停所有的应用程序线程的。第一次暂停从root对象开始标记存活的对象,这个阶段称为初始标记;第二次暂停是在并发标记之后,暂停所有应用程序线程,重新标记并发标记阶段遗漏的对象(在并发标记阶段结束后对象状态的更新导致)。第一次暂停会比较短,第二次暂停通常会比较长,并且 remark这个阶段可以并行标记。
而并发标记、并发清除、并发重设阶段的所谓并发,是指一个或者多个垃圾回收线程和应用程序线程并发地运行,垃圾回收线程不会暂停应用程序的执行,如果你有多于一个处理器,那么并发收集线程将与应用线程在不同的处理器上运行,显然,这样的开销就是会降低应用的吞吐量。Remark阶段的并行,是指暂停了所有应用程序后,启动一定数目的垃圾回收进程进行并行标记,此时的应用线程是暂停的。
Full Gc
Full gc是对新生代,旧生代,以及持久代的统一回收,由于是对整个空间的回收,因此比较慢,系统中应当尽量减少full gc的次数。如下几种情况下会发生full gc:
旧生代空间不足
持久代空间不足
CMS GC时出现了promotion failed和concurrent mode failure
统计得到新生代minor gc时晋升到旧生代的平均大小小于旧生代剩余空间
直接调用System.gc,可以DisableExplicitGC来禁止
存在rmi调用时,默认会每分钟执行一次System.gc,可以通过
Dsun.rmi.dgc.server.gcInterval=3600000来设置大点的间隔
日志分析图
[Full GC (System.gc()) 3654.523: [CMS: 101050K->82497K(917504K), 0.5917070 secs] 115116K->82497K(1271424K), [Metaspace: 77807K->77807K(1120256K)], 0.5926186 secs] [Times: user=0.51 sys=0.00, real=0.59 secs]
description
[Full GC (System.gc()) 3654.523:
Full GC:垃圾回收的停顿类型
3654.523:虚拟机启动以来的秒数
oldGenBefore->oldGenAfter(oldGenTotal),oldGenTimeConsuming
[CMS: 101050K-> 82497K(917504K), 0.5917070 secs]
CMS: CMS,全称Concurrent Low Pause Collector,是jdk1.4后期版本开始引入的新gc算法,在jdk5和jdk6中得到了进一步改进,它的主要适合场景是对响应时间的重要性需求大于对吞吐量的要求,能够承受垃圾回收线程和应用线程共享处理器资源,并且应用中存在比较多的长生命周期的对象的应用。CMS是用于对tenured generation的回收,也就是年老代的回收,目标是尽量减少应用的暂停时间,减少full gc发生的几率,利用和应用程序线程并发的垃圾回收线程来标记清除年老代.
oldGenBefore: gc前old区内存占用
oldGenAfter: gc后old区内存占用
oldGenTotal: old区内存总大小
heapBefore-heapAfter(heapTotal)
115116K->82497K(1271424K)
heapBefore: gc前堆内存大小
heapAfter: gc后堆内存大小
heapTotal: jvm堆内存总大小
metaspaceBefore->metaspaceAfter(metaspaceTotal)
[Metaspace: 77807K->77807K(1120256K)]
Metaspace: 永久保存区
metspaceBefore: gc前堆内存大小
metaspaceAfter: gc后堆内存大小
metaspaceTotal: 永久保存区总大小
fullGCTimeConsuming
0.5926186 secs]
gc耗时
userTimeCo
4000
nsuming->sysTimeConsuming->realTimeConsuming
[Times: user=0.51 sys=0.00, real=0.59 secs]
用户态消耗的CPU时间(用户时间)
内核态消耗的CPU时间(系统时间)
操作从开始到结束所经过的墙钟时间(实际时间)
To reader: 所述如有不妥之处,还望不吝指正~
相关文章推荐
- java对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- Android IPC进程间通讯机制
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- 介绍一款信息管理系统的开源框架---jeecg
- 聚类算法之kmeans算法java版本
- java实现 PageRank算法
- PropertyChangeListener简单理解
- c++11 + SDL2 + ffmpeg +OpenAL + java = Android播放器
- 插入排序
- 冒泡排序
- 堆排序
- 快速排序
- 二叉查找树