JVM学习(二) 垃圾收集器

内容来源于《深入理解Java虚拟机》-周志明

 

Serial收集器

单线程进行垃圾收集工作,使用复制算法。而且在工作时必须暂停其他所有工作线程,直到收集结束。

适用:运行在Client模式下的虚拟机

启用:-XX:+UseSerialGC

运行机制:新老代搭配 Serial / Serial Old收集器,新生代采用复制算法,暂停所有用户线程;老年代采用标记-整理算法,暂停所有用户线程。

 

 

ParNew收集器

是Serial收集器的多线程版。

适用:新生代垃圾收集

运行机制:多线程收集垃圾,收集方式同Serial收集器没有区别。默认开启线程数和CPU的数量相同,如果CPU非常多,可以通过参数 -XX:ParallelGCTreads 限制。

 

启用方式:

    1、直接指定 -XX:+UseParNewGC ,老年代默认使用 Serial Old收集器。

    2、使用 -XX:UseConcMarkSweepGC ,指定CMS作为老年代收集器,而新生代默认使用ParNew收集器

控制参数:

    -XX:SurvivorRatio 

    -XX:PretenureSizeThreshold

    -XX:HandlePromotionFaiure

    -XX:ParallelGCTreads  指定垃圾收集的线程数

 

Parallel Scavenge 收集器

并行收集器,可以多条线程并行工作,目标是达到一个可控制的吞吐量(运行用户代码时间/(运行代码时间+垃圾收集时间) ),高吞吐量可以提高利用CPU时间,快速完成运算任务。但用户线程依然处于等待状态。由于和吞吐量关系密切,经常被称为“吞吐量优先”收集器,

 

适用:新生代垃圾收集,后台运算而不需要太多交互任务的场景。选择它作为垃圾收集器,老年代只能选择Serial Old收集器 或Parallel Old 收集器(默认搭配)(Parallel Scavenge收集器无法与GMS收集器配合)。

启用命令:-XX:+UseParallelGC

控制参数:

    -XX:MaxGCPauseMillis 设置最大垃圾收集停顿时间,毫秒数

    -XX:GCTimeRatio 设置吞吐量大小,默认值是 99,即垃圾收集时间占比最大允许1%(1/(1+99))

    -XX:+UserAdaptiveSizePolicy 开关参数,开启自适应大小调节策略,配置该参数后,就不需要手工指定新生代的大小(-Xmn)、Eden与Survivor区比例(-XX:SurvivorRatio)、晋升老年代对象大小

(-XX:PretenureSizeThreshold)等细节参数了,虚拟机会根据当前系统运行情况收集性能监控,动态调整以提供最合适的停顿时间或者最大吞吐量。

最佳实践:使用者只需要设置好基本的内存数据,如:最大堆内存(-Xmx  测试后无法设置启动),然后使用MaxGCPauseMillis和GCTimeRatio两个参数设立一个优化目标,其他细节就可以由虚拟机完成。

 

Serial Old 收集器

是Serial收集器的老年代版本,同样是一个单线程收集器,使用标记-整理算法。

适用:

       1.JDK1.5前与Parallel Scavenge收集器搭配;

       2.作为CMS收集器的后备方案,在并发收集发生Concurrent Mode Failure时使用。

 

Parallel Old 收集器

是Parallel Scavenge收集器的老年代版本,使用多线程和标记-整理算法。

 

GMS 收集器

CMS(Concurrent Mark Sweep)收集器,是一种以获取最短回收停顿时间为目标的收集器。

适用:老年代收集。大部分应用在Java应用集中在互联网或者B/S系统的服务端上,注重服务响应速度、停顿时间最短,给用户带来较好体验。

4个工作步骤:

    1.初始标记    线程停顿,只标记GC Roots 能直接关联到的对象

    2.并发标记    并发进行,GC Roots Tracing过程

    3.重新标记    线程停顿,修正并发标记过程中因用户程序继续运作而导致标记产生变动的那部分对象的标记记录,这个阶段比初始标记稍长。

    4.并发清除    

缺点:

    对CPU资源非常敏感。默认启动回收线程数是 (CPU数量+3)/ 4。

    无法处理浮动垃圾,可能出现“Concurrent Mode Failure”失败而导致另一次Full GC的产生。

    标记-清除算法导致内存碎片。

参数设置:

    -XX:+UseConcMarkSweepGC:新生代使用并行收集器,老年代使用CMS+串行收集器

    -XX:ParallelCMSThreads:设定CMS的线程数量

    -XX:CMSInitiatingOccupancyFraction:设置CMS收集器在老年代空间被使用多少后触发,默认为68%

    -XX:+UseCMSCompactAtFullCollection:设置CMS收集器完成垃圾收集后是否要进行一次内存碎片的整理,默认开启

    -XX:CMSFullGCsBeforeCompaction:设定进行多少次CMS垃圾回收后,进行一次内存压缩,默认0

    -XX:+CMSClassUnloadingEnabled:允许对类元数据区进行回收

    -XX:CMSInitiatingPermOccupancyFraction:当永久区占用率达到这一百分比时,启动CMS回收(前提是-    XX:+CMSClassUnloadingEnabled激活了)

    -XX:UseCMSInitiatingOccupancyOnlyn:表示只在到达阈值的时候才进行CMS回收

    -XX:+CMSIncrementalMode:使用增量模式,比较适合单CPU。增量模式在JDK 8中标记为废弃,并将在JDK 9中彻底移除。

 

 

G1 收集器

G1(Garbage-First) 是一款面向服务端应用的垃圾收集器,将来替换CMS收集器。与其他收集器最大差别,它是将Java堆内存划分为多个大小相等的独立区域(Region),虽然还保留着新生代和老年代的思想,但是新生代和老年代不再是物理隔离了,而是一部分Region(可以不连续)的集合。

特点:

    并行与并发。

    分代收集。不需要其他垃圾收集器配合,可以独立管理整个GC堆

    空间整理。整体看是基于标记-整理算法实现的,从局部(两个Region之间)上看是基于复制算法实现的。不会产生内存空间碎片。

    可预测的停顿。相比CMS,除了追求低停顿外,还能建立可预测的停顿时间模型,能让使用者明确指定在一个长度为M毫秒的时间片段内,消耗在垃圾收集上的时间不得超过N毫秒。G1跟踪每一个Region里面的垃圾堆积的价值大小(回收所获得的空间大小以及回收所需时间的经验值),在后台维护一个优先列表,每次根据允许的时间,优先回收价值最大的Region,从而提高收集效率。

工作步骤

    初始标记    线程停顿,只标记GC Roots 能直接关联到的对象

    并发标记    并发进行,GC Roots Tracing过程

    最终标记    线程停顿,修正并发标记过程中因用户程序继续运作而导致标记产生变动的那部分对象的标记记录。虚拟机将这段时间对象变化记录在线程Remembered Set中,

    筛选回收    对各个 Region的回收价值和成本进行排序,根据用户期望的GC停顿时间来制定回收计划。

配置参数:

      -XX:+UseG1GC:使用G1回收器

    -XX:MaxGCPauseMillis:设置最大垃圾收集停顿时间

    -XX:GCPauseIntervalMillis:设置停顿间隔时间

    

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值