按线程数分(垃圾回收线程数)
可以分为串行垃圾回收器和并行垃圾回收器
适用场景
按照工作模式分
可以分为并发式垃圾回收器和独占式垃圾回收器
按碎片处理方式分
可分为压缩式垃圾回收器和非压缩式垃圾回收器
工作的内存区间分
可分为年轻代垃圾回收器和老年代垃圾回收器
评估 GC 的性能指标
总结
评估 GC 的性能指标:吞吐量(throughput)
评估 GC 的性能指标:暂停时间(pause time)
评估 GC 的性能指标:吞吐量 vs 暂停时间
有了虚拟机,就一定需要收集垃圾的机制,这就是Garbage Collection,对应的产品我们称为Garbage Collector。
7款经典回收器与垃圾分代之间的关系
Serial 回收器举例
这个收集器是一个单线程的收集器,“单线程”的意义:
设置 Serial 垃圾回收器
Serial 回收器总结
并行 Or 串行
由于ParNew收集器基于并行回收,那么是否可以断定ParNew收集器的回收效率在任何场景下都会比Serial收集器更高效?并不能
CMS整个过程比之前的收集器要复杂,整个过程分为4个主要阶段,即初始标记阶段、并发标记阶段、重新标记阶段和并发清除阶段。(涉及STW的阶段主要是:初始标记 和 重新标记)
为什么 CMS 不采用标记-压缩算法呢?
优点
缺点
1.-XX:+UseConcMarkSweepGC:手动指定使用CMS收集器执行内存回收任务。
开启该参数后会自动将-XX:+UseParNewGC打开。即:ParNew(Young区)+CMS(Old区)+Serial Old(Old区备选方案)的组合。
2.-XX:CMSInitiatingOccupanyFraction:设置堆内存使用率的阈值,一旦达到该阈值,便开始进行回收。 1)JDK5及以前版本的默认值为68,即当老年代的空间使用率达到68%时,会执行一次CMS回收。JDK6及以上版本默认值为92% 2)如果内存增长缓慢,则可以设置一个稍大的值,大的阀值可以有效降低CMS的触发频率,减少老年代回收的次数可以较为明显地改善应用程序性能。 3)反之,如果应用程序内存使用率增长很快,则应该降低这个阈值,以避免频繁触发老年代串行收集器。因此通过该选项便可以有效降低Full GC的执行次数。
3.-XX:+UseCMSCompactAtFullCollection:用于指定在执行完Full GC后对内存空间进行压缩整理,以此避免内存碎片的产生。不过由于内存压缩整理过程无法并发执行,所带来的问题就是停顿时间变得更长了。
4.-XX:CMSFullGCsBeforeCompaction:设置在执行多少次Full GC后对内存空间进行压缩整理。
5.-XX:ParallelCMSThreads:设置CMS的线程数量。 1)CMS默认启动的线程数是 (ParallelGCThreads + 3) / 4,ParallelGCThreads是年轻代并行收集器的线程数,可以当做是 CPU 最大支持的线程数 2)当CPU资源比较紧张时,受到CMS收集器线程的影响,应用程序的性能在垃圾回收阶段可能会非常糟糕。
HotSpot有这么多的垃圾回收器,那么如果有人问,Serial GC、Parallel GC、Concurrent Mark Sweep GC这三个GC有什么不同呢?
JDK 后续版本中 CMS 的变化
既然我们已经有了前面几个强大的 GC ,为什么还要发布 Garbage First(G1)GC?
为什么名字叫 Garbage First(G1) 呢?
并行与并发兼具
分代收集
G1的分代,已经不是下面这样的了
G1的分区是这样的一个区域
这是G1相对于CMS的另一大优势,G1除了追求低停顿外,还能建立可预测的停顿时间模型,能让使用者明确指定在一个长度为M毫秒的时间片段内,消耗在垃圾收集上的时间不得超过N毫秒。
1.-XX:+UseG1GC:手动指定使用G1垃圾收集器执行内存回收任务
2.-XX:G1HeapRegionSize:设置每个Region的大小。 值是2的幂,范围是1MB到32MB之间,目标是根据最小的Java堆大小划分出约2048个区域。默认是堆内存的1/2000。
3.-XX:MaxGCPauseMillis:设置期望达到的最大GC停顿时间指标 VM会尽力实现,但不保证达到。默认值是200ms
4.-XX:+ParallelGCThread:设置STW工作线程数的值。最多设置为8
5.-XX:ConcGCThreads:设置并发标记的线程数。 将n设置为并行垃圾回收线程数(ParallelGcThreads)的1/4左右。
6.-XX:InitiatingHeapOccupancyPercent:设置触发并发GC周期的Java堆占用率阈值。 超过此值,就触发GC。默认值是45。
G1 收集器的常见操作步骤
G1的设计原则就是简化JVM性能调优,开发人员只需要简单的三步即可完成调优:
G1中提供了三种垃圾回收模式:YoungGC、Mixed GC和Full GC,在不同的条件下被触发。
设置 H 的原因
Regio的内部结构
G1 回收器垃圾的主要环节
G1 GC的垃圾回收过程主要包括如下三个环节:
顺时针,Young GC --> Young GC+Concurrent Marking --> Mixed GC顺序,进行垃圾回收
大致的回收流程
G1 回收器垃圾回收过程:Remembered Set(记忆集)
存在的问题
解决方法
总结
G1 回收过程:年轻代 GC
开始如下回收过程:
备注:
混合回收的细节
导致G1 Full GC的原因可能有两个:
G1 回收器的补充
G1 回收器的优化建议
截止JDK1.8,一共有7款不同的垃圾收集器。每一款的垃圾收集器都有不同的特点,在具体使用的时候,需要根据具体的情况选用不同的垃圾收集器。
Java垃圾收集器的配置对于JVM优化来说是一个很重要的选择,选择合适的垃圾收集器可以让JVM的性能有一个很大的提升。怎么选择垃圾收集器?
最后需要明确一个观点:
通过阅读GC日志,我们可以了解Java虚拟机内存分配与回收策略。
内存分配与垃圾回收的参数列表