虚拟机3.5 垃圾收集器

来源:互联网 发布:出入境旅游数据统计 编辑:程序博客网 时间:2024/06/16 19:12

HotSpot虚拟机的垃圾收集器
垃圾收集器
3.5.1 Serial收集器
特征‘Stop the World’,GC时需停止其他所有线程,且用户不知情,体验不好,简单高效,没有线程交互的开销,在Client模式下的jvm收集几十兆到一两百兆的新生代停顿时间一般在100ms以内,单个CPU下效果可以。
3.5.2ParNew收集器
Serial收集器的多线程版本。 是Server模式下首选的新生代收集器,这与性能无关,只有它及Serial收集器能和CMS收集器配合工作。适合多CPU时的选择。
并行:多个GC线程一同运行,但用户线程是等待的
并发:GC线程和用户线程同时执行(可能交替执行)在不同的CPU上。
3.5.3 Parallel Scavenge收集器
此收集器的关注点是达到高吞吐量(运行用户代码时间 / CPU总消耗时间(用户代码时间+垃圾手机时间)),其他类型收集器是关注缩短用户线程的停顿时间。
停顿时间越短,和用户交互的体验更好。 吞吐量高,在后台运算效率更高。
-XX:MaxGCPauseMillis:最大垃圾收集停顿时间
这个时间的设置如果太小,垃圾收集次数更频繁,如原来10秒收集一次,每次停顿100ms,现在5秒收集一次,每次停顿70ms,停顿时间由100变成70ms,但吞吐量变低了。
-XX:GCTimeRatio:间接设置吞吐量大小的时间,范围:1~99,公式:ratio /(1+ratio),表示GC时间 / 总CPU时间 的比率。
GC自适应调节策略:无需指定新生代大小(-Xmn)、Eden和Survivor区的比例,(SurvivorRatio),晋升老年代对象大小等细节参数。
3.5.4Serial Old收集器
是Serial老年代版本,用标记整理算法.主要Client模式下使用,
主要用途有二:搭配Parallel Scavenge使用; 作为CMS的后备预案。
3.5.5Parallel Old收集器
适用于吞吐量优先的Server模式场合,收集老年代,和Parallel Scavenge收集器收集新生代搭配使用.
3.5.6 CMS收集器
以并发收集,缩短回收停顿时间,用户体验好为目标,适用于面向服务端。
运作过程有4个步骤
①初始标记:标记GC Roots可以关联到的对象,速度快。
②并发标记:进行GC Roots Tracing过程,时间较长。
③重新标记:修正并发标记时因用户程序运行导致标记发生变动的一部分,比①时间稍长。
④并发清除:
①和③需要‘stop the world’。
缺点有三个:
①在并发阶段(②和④),占用一部分cpu资源导致用户程序变慢,总吞吐量降低。CMS默认启动回收线程数是(CPU/4)+3/4.即使交互运行,效果也不好。
②CMS收集器无法处理浮动垃圾。在并发清理时,用户线程同时运行会有新的垃圾不断产生,无法在当次GC掉,只能下次GC,这些就是‘浮动垃圾’。
-XX:CMSInitiatingOccupancyFraction可以设置当老年代占用多大比例的空间即被激活GC。如果比例设置过高,没有足够的余留空间给用户线程使用,则并发GC失败,启用后备预案Serial Old进行GC,此时性能降低。
③标记-清除算法清除老年代,造成大量空间碎片。无法分配大对象时,会进行一次Full GC,默认在此之前会进行碎片整理。
3.5.7 G1收集器
前沿的面向服务端应用的收集器。特点如下
①并行与并发:
②分代收集:不同方式处理新生代、老年代
③空间整合:整体是‘标记-整理’收集,局部是‘标记-复制’收集,避免碎片的产生。
④可预测的停顿时间:明确指定在X毫秒时间内,GC时间不超过Y毫秒。
使用G1时,堆内存布局是多个大小相等的独立区域region,新生代和老年代不再物理隔离,都是region的集合。
可预测停顿时间的原因是 有计划的避免在整体Java堆中进行全区域的GC。G1根据回收的性价比(所获空间 / 所需时间),维护一个优先列表。根据允许的收集时间,优先回收性价比高的region,从而提高收集效率。
存在问题:region并不是孤立的,有可能被堆中的任意对象引用,做可达性分析时需要扫描整个堆内存,回收新生代应尽量避免扫描老年代内存。
解决办法:所有收集器都是使用Remembered Set避免全堆扫描.在G1中每一个region都有一个对应的remembered set,程序在对Reference类型数据进行写操作时,会Write Barrier暂时中断写操作,检查Reference数据引用的对象是否处于不同的region中(在分代中就是检查老年代是否引用了新生代)。如果是,则记录到reference数据对应的remembered set中。当GC时,在gc根节点的枚举范围中加入remembered set即可避免全堆扫描,避免遗漏。
G1运作大致步骤(不包含remembered set 操作):
①初始标记
②并发标记
③最终标记:和CMS类似,需要把对象变化记录存在线程remembered set logs中,然后合并到remember set,可并行执行(不是并发)。
④筛选回收

3.5.8 理解GC日志
33.125: [GC [DefNew: 3324K->152K(3712K), 0.0025925 secs] 3324K->152K(11904K), 0.0031680 secs]
33.125:虚拟机启动后经过的秒数
GC:表示GC类型,类似还有 Full GC
DefNew(新生代):表示发生的区域,类似还有Tenured (老年代 )Perm(方法区)
3324K->152K(3712K):GC前该内存区域已使用容量->GC后该内存区域已使用容量(该区域总容量)
3324K->152K(11904K):GC前Java堆已使用容量->GC后Java堆已使用容量(Java堆总容量)
0.0031680 :GC所用时间。

[Times: user=0.01 sys=0.00, real=0.02 secs]
user时间:用户消耗时间,sys:内核态消耗时间,real:总的墙钟时间(包含线程等待、磁盘I/O等时间)

原创粉丝点击