jvm认识与探究(四)GC:垃圾回收

官方文档:https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/cms.html

一、初识垃圾回收

1.确定垃圾对象

可达性分析:通过GC Root对象向下寻找,查看某个对象是否可达,不可达则是垃圾对象。
GC Root:Thread、类加载器、虚拟机栈的本地变量表、static成员、常量引用、本地方法栈的变量等可以作为GC Root。

2.垃圾回收名词解释

Minor GC:年轻代的垃圾回收叫做Minor GC。
Major GC:老年代的垃圾回收叫做Major GC。
FULL GC:通常情况下我们认为Minor GC + Major GC 是FULL GC,但严格意义上来说还需要加上Metaspace GC 才叫做FULL GC。
STW:Stop-The-World机制简称为STW,即当jvm执行垃圾回收的时候会停止我们所有的业务线程。

二、垃圾收集算法

1.标记-清除(Mark-Sweep)

标记:找出内存中需要回收的对象,并把他们标记起来。
堆中的所有对象都会被扫描一遍,才能确定需要回收的对象,比较耗时。

在这里插入图片描述

清除:清除需要被回收的对象,释放对应的内存空间。
标记清除之后会产生大量的不连续的内存空间碎片,空间碎片太多会导致以后在程序运行过程当中需要分配大对象时,无法找到足够的连续内存空间,从而提前触发另外一次垃圾回收。

在这里插入图片描述

2.复制(Copying)

将内存划分为两块,每次只用其中一块

在这里插入图片描述

当其中一块内存不能再为新的对象分配内存空间,就将存活的对象复制到另一块空间,并且将使用过的内存空间全部清除掉。

在这里插入图片描述

缺点:空间利用率低。同一时间只用到了一半的内存空间。

3.标记-整理(Mark-Compact)

标记过程仍然和"标记-清除"算法一样,但是后续步骤不是对可回收对象进行清除,而是让所有存活对象向一端移动,然后将存活对象边界以外的内存全部清除。

在这里插入图片描述

让所有存活对象向一端移动,清理掉边界以外的对象。

在这里插入图片描述

4.分代算法使用

Young区:复制算法(一般对象在分配之后,生命周期较短,将少量的存活对象从Eden区复制到Survivor区)
Old区:标记-清除或标记-整理算法(Old区对象存活时间比较长,复制会降低效率,做标记再清除或整理效率会更高)

三、垃圾收集器

在这里插入图片描述

1.Serial

serial收集器是最基本、发展历史最悠久的收集器,在jdk1.3.1之前是虚拟机年轻代垃圾回收的唯一选择。

串行收集器使用一个线程执行所有垃圾收集工作,这使得它相对高效,因为线程之间没有通信开销。它最适合单处理器机器,因为它不能利用多处理器硬件,尽管对于具有小数据集(大约100 MB)的应用程序,它在多处理器上也很有用。串行收集器在某些硬件和操作系统配置上是默认选择的,或者可以使用-XX:+UseSerialGC选项显式启用。

优点:简单高效,拥有很高的单线程收集效率
缺点:回收过程需要暂停所有线程
算法:复制算法
分代:年轻代

在这里插入图片描述

2.ParNew

Serial收集器的多线程版本

优点:在多CPU硬件环境下,比Serial效率高
缺点:收集过程暂停所有应用程序线程,单CPU硬件环境下比Serial效率低
算法:复制算法
分代:年轻代

在这里插入图片描述

3.Parallel Scavenge

Parallel Scavenge收集器是一个年轻代收集器,它也是使用"复制"算法的收集器,又是并行的多线程收集
器,但是Parallel Scavenge更关注系统的吞吐量

4.Serial Old

Serial Old收集器是Serial收集器的老年代版本,也是一个单线程收集器,不同的是采用"标记-整理"算法。

在这里插入图片描述

5.Parallel Old

Parallel Old收集器是Parallel Scavenge收集器的老年代版本,也是多线程,不同的是它使用的"标记-整理"算法。

5.CMS(Concurrent Mark Sweep)

CMS(Concurrent Mark Sweep)收集器是一种以获取最短回收停顿时间为目标的老年代收集器,采用"标记-清除"算法,所以会产生大量空间碎片,并发阶段会降低吞吐量。

执行流程
a.初始标记----标记GC Roots能关联到的对象----stop the world
b.并发标记----进行GC Root 追踪
c.重新标记----修改并发标记因用户程序变动的内容----stop the world
d.并发清理

在这里插入图片描述

6.G1(Garbage-First)

G1(Garbage-First)垃圾收集器是一种服务器风格的垃圾收集器,目标是具有大内存的多处理器机器。它是一个试图在实现高吞吐量的同时,再以高概率实现垃圾收集无停顿时间为目标的收集器,并同时使用于老年代和年轻代,使用"标记-整理"算法。JDK8成熟并推荐使用,JDK9以后默认垃圾收集器。

使用G1收集器时,Java堆的内存布局与就与其他收集器有很大差别,它将整个Java堆划分为多个大小相等的独立区域(Region),虽然还保留有新生代和老年代的概念,但新生代和老年代不再是物理隔离的了,它们都是一部分Region(不需要连续)的集合。

在这里插入图片描述

执行流程
a.初始标记----标记GC Roots能关联到的对象----stop the world
b.并发标记----标记GC Roots可达性对象,并收集region存活对象信息
c.最终标记----标记在并发阶段因用户程序发生变化的对象----stop the world
d.筛选回收----对各region的回收价值和成本排序,根据用户期望GC停顿时间进行回收----stop the world

在这里插入图片描述

7.吞吐量和停顿时间

吞吐量:运行用户代码时间/(运行用户代码时间+垃圾收集时间)
停顿时间:垃圾收集器执行回收暂停用户线程的时间

这两个指标是评价一个垃圾收集器优势的标准,jvm调优同样会观察这两个指标。
8.垃圾收集器分类

串行收集器:Serial、Serial Old

只有一个垃圾回收线程执行,用户线程暂停。适用于内存较小的嵌入式程序。

并行收集器[吞吐量优先]:Parallel Scavenge、Parallel Old

多条垃圾回收线程并行工作,用户线程暂停。适用于后台处理耗CPU场景。

并发收集器[停顿时间优先]:CMS、G1

用户线程和垃圾回收线程同时执行(不一定并行,可能交替执行),更少的并以不停顿用户线程为目标的收集器。适用于多交互服务器的场景,如web。

官方选择垃圾收集器参考:https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/collectors.html#sthref28

开启使用垃圾收集器
串行:
-XX:+UseSerialGC
-XX:+UseSerialOldGC
并行:
-XX:+UseParallelGC
-XX:+UseParallelOldGC
并发:
-XX:+UseConcMarkSweepGC
-XX:+UseG1GC

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值