垃圾回收器
2020-09-30
-XX:+PrintCommandLineFlags:查看命令行参数(可打印出使用的是哪个垃圾回收器)。
Serial回收器:串行回收 #
-
Client模式下默认的新生代垃圾收集器。
-
Serial收集器采用复制算法、串行回收和“Stop-The-World”机制的方式执行内存回收。
-
Serial Old-对应的老年代垃圾收集器,同样采用串行回收和“Stop-The-World”机制,只不过内存回收算法使用的是标记-压缩算法。
- Serial Old是Client模式下默认的老年代的垃圾收集器。
- Serial Old在Server模式下主要有两个用途:①与新生代的Parallel Scavenge配合使用;②作为老年代CMS收集器的后备垃圾收集方案。
-
这个收集器是一个单线程的收集器,在它进行垃圾收集时,必须停掉其他所有的工作线程,直到它收集结束。
-
-XX:+UseSerialGC:指定新生代Serial,老年代Serial Old GC。
ParNew回收器:并行回收 #
-
多线程的Serial。
-
-XX:+UseParNewGC:指定年轻代ParNew,不影响老年代。
-
-XX:ParallelGCThreads:限制线程数量,默认开启与cpu数据相同的线程数。
Parallel Scavenge回收器:吞吐量优先 #
-
同样采用并行回收、复制算法、STW机制。
-
Parallel Scavenge收集器的目标是达到一个可控的吞吐量,它也被称为吞吐量优先的垃圾收集器。
-
自适应调节机制也是Parallel Scavenge与ParNew的一个重要区别。
-
高吞吐量可以高效的利用cpu时间,尽快的完成程序的运算任务。主要用于在后台运算而不需要太多交互的任务。
-
应用场景:执行批量处理、订单处理、工资支付、科学计算的应用程序。
-
Parallel Old:老年代垃圾收集器,采用标记-压缩算法、并行回收、STW机制。
-
-XX:+UseParallelGC:手动指定年轻代使用Parallel;-XX:+UserParallelOldGC:手动指定老年代。这两个参数,当指定一个,另一个也会被开启。
-
-XX:ParallelGCThreads:设置年轻代并行的线程数。
-
-XX:+UseAdaptiveSizePolicy:设置Parallel收集器具有自适应调节策列。
CMS回收器:低延迟(Concurrent-Mark-Sweep) #
-
HotSpot虚拟机中第一款真正意义上的并发收集器,实现了让垃圾收集线程与用户线程同时执行。
-
采用标记清除算法,也会导致stw。
-
运行过程:
- 初始标记:仅标记GC Roots能直接关联到的对象。速度很快,需要stw。
- 并发标记:从GC Roots的直接关联对象开始遍历整个对象图的过程,这个过程耗时较长但不需要停顿用户线程。
- 重新标记:修正并发标记期间因用户程序继续运作而导致标记产生变动的那一部分对象的标记记录,这个阶段的stw一般会比初始标记稍长一些。
- 并发清除:清理标记阶段判断已经死亡的对象,释放内存空间。这个阶段可与用户线程并发。
-
由于在垃圾收集阶段用户线程仍在执行,所以在CMS回收过程中,要保证应用程序线程有足够的内存可用。因此,CMS收集器不能像别的收集器一样等到老年代几乎完全填满了才进行垃圾回收,而是在堆内存达到某一个阈值时,便开始进行回收。当CMS运行期间,内存无法满足程序要求,这时虚拟机会启用预备方案:临时使用Serial Old进行垃圾回收。
-
CMS采用标记-清除算法,只能采用空闲列表进行内存分配。
-
优点:低延迟,并发收集。
-
缺点:产生内存碎片;对cpu资源非常敏感,因为占用了一部分线程,会导致吞吐量降低;无法处理浮动垃圾(并发标记阶段如果产生新的垃圾,cms无法对这些垃圾进行标记,会导致这些垃圾无法及时的被回收)。
-
-XX:+UseConcMarkSweepGC:手动指定使用CMS收集器。
G1回收器:区域分代化 #
-
-XX:+UseG1GC:启用G1。
-
目标:延迟可控的情况下获取尽可能高的吞吐量。
- G1是一个并行回收器,它把堆内存分割为很多不相关的区域。使用不同的region来表示Eden区、幸存者0区、幸存者1区、老年代等。
- G1有计划的避免在java堆中进行全区域的垃圾回收,G1跟踪各个region里面的垃圾堆积的价值大小(回收所获得的空间大小以及回收所需时间的经验值),在后台维护一个优先列表,每次根据允许的收集时间,优先回收价值最大的region。
- 由于这种方式的侧重点在于回收垃圾最大量的区间,所以给G1取一个名字:垃圾优先(Garbage First)。
-
优点:
- 并行性:G1在回收期间,可以多个GC线程同时工作。此时用户线程stw。
- 并发性:G1部分工作能与用户线程同时执行。
- 分代收集:G1仍属于分代型垃圾收集器。但是不再要求整个Eden、年轻代、或者老年代都是连续的,也不再坚持固定大小和数量。它同时兼顾年轻代和老年代。
- 空间整合:内存是以region为基本单位的。region之间是复制算法,整体上看可以看作是标记-压缩算法。可以避免产生内存碎片。
- 可预测的时间停顿模型:能让使用者明确指定在一个长度为M毫秒的时间片段内,消耗在垃圾收集上的时间不得超过N毫秒。
-
-XX:MaxGCPauseMillis 设置期望达到的最大Gc停顿时间指标(JVM会尽力实现,但不保证达到)。默认值是200ms
-
Remembered Set:一个对象可能被不同区域region所引用。当有其它region指向本region时,记录其他region的引用。
-
G1垃圾回收的过程
- 年轻代GC:①扫描根(包含RSet);②更新RSet;③处理RSet;④复制对象;⑤处理引用。
- 并发标记过程:①初始标记(标记根节点直接可达的对象,会触发一次年轻代GC);②根区域扫描(扫描survivor区能直达老年代的对象并标记被引用的对象);③并发标记(若发现一个region区域全是垃圾,则直接回收);④再次标记;⑤独占清理;⑥并发清理阶段。
- 混合回收:回收整个Yong Region和一部分Old Region。
- 如果上述方式不能正常工作,就会触发Full GC。