相关文章
文章目录
Serial
Serial垃圾收集器是一种年轻代收集器,看名字就知道它是单线程的。这个单线程有两方面的含义,一是垃圾收集只用了一个线程,另一个含义是会发生“Stop the World”。使用复制算法。
- -XX:+UseSerialGC
这款垃圾收集器在单CPU上运行比其他的更好,因为其避免的线程切换的性能损耗。试用一些小型系统,比如桌面应用、小设备应用等,这类系统的年轻代很小,系统停顿的时间也很短。这款垃圾收集器是-client模式下的默认年轻代收集器。
Serial Old
这款收集器是老年代收集器,单线程实现,Stop the World,使用标记-整理算法。
配合Serial以及作为CMS在Concurrent Mode Failure时的备用垃圾收集器。
- -XX:+UseSerialGC
ParNew
- 年轻代垃圾收集器
- 多线程:处理采用多线程并行回收外,其他与Serial一样。
- 算法:复制算法
- -XX:+UseParNewGC : 采用ParNew + Serial Old
CMS (Concurrent Mark Sweep)
- 老年代垃圾收集器
- 多线程
- 基本算法:标记-清除算法
- -XX:+UseConcMarkSweepGC : ParNew + CMS + Serial Old
- 过程:
- 初始标记:分析于GC Roots直接连接的对象,会Stop the world,但是速度很快。
- 并发标记:并发地进行可达性分析,不会停顿系统,时间很长。
- 重新标记:对在并发标记过程,重新变更的引用进行可达性分析,会Stop the world。速度比初始标记时间略长,但是远小于并发标记。
- 并发清除:并发地进行对象清除。时间较长,但是可以与工作线程同时进行。
- 优点:很短的回收停顿时间
- 缺点3个:
- 对CPU资源很敏感:并发标记会降低系统处理能力,并发标记占用的线程数是(cpu数 + 3)/ 4。在cpu数量很少时,影响尤为严重。增量式CMS采用抢占式线程切换,效果一般。-XX:ParallelGCThreads控制最大线程数。
- 无法有效处理浮动垃圾,导致Concurrent Mode Failure而触发另一次Full GC:所谓浮动垃圾是指在并发清除阶段工作线程并没有停止,这这段时间内,需要保留一些内存供工作线程使用,如果内存不够,就会Stop the world,临时采用Serial Old进行回收,这就很耗时了。-XX:CMSInitiatingOccupancyFraction控制使用多少后进行CMS GC。
- 内存空间碎片太多:由于采用的是标记-清除算法,会产生很多空间碎片,导致虽然还剩很多内存,但是找不到一块连续的内存来存放较大的对象。这时就需要采用Serial Old收集器来进行Full GC,并且整理空间碎片。-XX:+UseCMSCompactAtFullCollection,默认是开启的,在发生Full GC时,进行内存整理。-XX:+CMSFullGCsBeforeCompaction在经过多少次Full GC后整理一次碎片,默认为0,表示每次都整理。
Parallel Scavenge
- 年轻代收集器
- 多线程
- 适用于吞吐量优先的业务
- -XX:+UseParallelGC : Parallel Scavenge + Serial Old
- -XX:GCTimeRatio 调整GC占用的总时间,默认是99,含义是GC占用时间为 1/(1+99) = 1%。
- -XX:MaxGCPauseMillis 控制最大停顿时间。减少最大停顿时间可能会导致吞吐量的下降。
- -XX:+UseAdaptiveSizePolicy : 自适应调节策略,打开后不需要手动调节-XX:SurvivorRatio -XX:PretenureSizeThreshold -XX:MaxTenuringThreshold等。
Parallel Old
- 老年代收集器
- 多线程
- 配合Parallel Scavenge使用
- -XX:+UseParallelOldGC
- 适用于吞吐量优先的业务
G1 (Garbage First)
- 将内存空间划分为一个个区域,称为Region。年轻代和老年代由一些Region组成。
- 每个Region维护一个Remembered Set,记录当前Region被其他Region引用的信息,这样就不必扫描整个剩余Region。
- 特点:
- 并发并行
- 分代收集
- 空间整理
- 化整为零
- 可预测的停顿:建立可预测停顿时间模型,按照每个Region的垃圾回收性价比(回收垃圾/占用时间)维护一个优先列表,先回收价值高的Region,所以称为Garbage First。
- 步骤
- 初始标记:STW
- 并发标记:这段时间工作线程又产生的引用变动记录在Remembered Set Logs里。
- 最终标记:STW,将Remembered Set Logs合并到Remembered Set中。
- 筛选回收:根据Region价值优先列表和用户期望的GC停顿时间来制定回收计划,并执行。
GC日志
- -XX:PrintGCDetials
- GC发生时间:系统启动到GC时的秒数
- [GC和[Full GC :代表垃圾收集的停顿类型,并不是区分新生代GC和老年代GC。比如ParNew GC也可能因为担保失败而发生STW。
- [DefNew [ParNew [Perm : GC发生的区域
- 方括号内的3323K->2341K(1234132k):GC前使用量,GC后使用量,整个区总容量
- 方括号外:代表Java堆
- GC使用时间:单位秒,如果给出具体时间user=用户态消耗CPU时间,sys=内核态消耗CPU时间,real=操作从开始到结束的墙钟时间(包括所有的时间,不止CPU消耗的时间)。
内存分配与回收策略
- 优先分配在Eden区
- 大对象直接进入老年代
- 长期存活的对象进入老年代
- 动态对象年龄判定
- 空间分配担保:如果老年代的最大连续内存大小大于历次晋升到老年代对象的平均大小,并且-XX:HandlePromotionFailure=true(表示允许担保失败),则可以尝试进行Minor GC;否则改为进行Full GC。-XX:HandlePromotionFailure在jdk1.6.24不再使用,只通过历次晋升到老年代对象的平均大小与果老年代的最大连续内存大小决定。