JVM-垃圾回收(GC)

垃圾回收

什么是垃圾:

没有对象引用的就是垃圾 (= .=)

请添加图片描述

红色部分由于没有对象引用,此时可以认为它是一坨垃圾

如何找到垃圾:

1.引用计数

在这里插入图片描述

有一次引用,那么我们就将该对象引用次数+1.当引用数为0时,表明没有对象引用。

无法解决循环引用的问题

在这里插入图片描述

循环依赖,没有被外部引用。实质上他们已经是一堆垃圾了。

2.根可达算法

什么是根对象:

线程栈对象、静态变量、常量池、JNI指针(C/C++本地方法用的变量)

在这里插入图片描述

常用的垃圾回收算法:

1、标记清除(mark-sweep)

适合存活对象比较多,需要清除的对象比较少,扫描两次

缺点:会产生大量的内存碎片

在这里插入图片描述

2、拷贝(copying)

它将可用内存按容量划分为大小相等的两块,每次只使用其中的一块,当这一块的内存用完了,就将还存活着的对象复制到另外一块上面,然后再把已使用过的内存空间一次清理掉。

适用于存活对象比较少,只扫描一次。没有内存碎片(伊甸区)

缺点:

1、对象引用需要调整

2、将可使用内存降低了一半

在这里插入图片描述

3、标记压缩(mark-compact)

标记整理其中的标记过程仍然与标记清除算法一样,但后续步骤不是直接对可回收对象进行清理,而是让所有存活的对象都向内存空间一端移动,然后直接清理掉边界以外的内存,如下图所示。

缺点:

1、对象引用需要调整

2、扫描两次
请添加图片描述

JVM内存分代模型

在这里插入图片描述

1.部分垃圾回收器使用的模型

​ ZGC/Shenandoah之外的GC都是使用逻辑分代模型

​ G1是逻辑分代,物理不分代

2.新生代+老年代+永久代(1.7)PermGeneration / 元数据区(1.8) MetaSpace

  • 永久代 元数据 -Class
  • 永久代必须指定大小限制,且确定后不可以修改。元数据可以设置,也可以不设置,无上限
  • 字符串常量 1.7-永久代 1.8 -堆
  • MethodArea 是逻辑概念 - 永久代、元数据是具体实现

在这里插入图片描述

可以通过参数改变分代模型的比例

对象什么时候进入老年代

  • 大对象直接进入老年代

  • -XX:MaxTenuringThreshold 指定次数(YGC)

    • Parallen Scavenge 15
    • CMS 6
    • G1 15
  • 动态年龄:

    • Hotspot遍历所有对象时,按照年龄从小到大对其所占用的大小进行累积,当累积的某个年龄大小超过了survivor区的一半时,取这个年龄和MaxTenuringThreshold中更小的一个值,作为新的晋升年龄阈值。

在这里插入图片描述

常见垃圾回收器

在这里插入图片描述

1.Serial

a stop-the-world,copying collector which uses a single GC thread

单线程收集器、收集垃圾时,会停止其他任务执行,采用复制算法

2.Serial Old

a stop-the-world,mark-sweep-compact collector that uses a single GC thread

单线程,采用标记清除/压缩算法

3.Parallel Scavenge

a stop-the-world,copying collector which uses multiple GC threads

多线程收集器,复制算法

4.Parallel Old

a compacting collector that uses multiple GC threads

多线程收集器,压缩算法

5.Parallel New

a stop-the-world ,copying collector which uses multiple GC threads

// 与Parallel Scavenge 相比做了一些增强用于与CMS配合

It differs from “Parallel Scavenge” in that it has enhancements that make it usable with CMS

PN 响应时间优先

PS 吞吐量优先

6.CMS

1.4 后期引入,开启并发回收

concurrent mark sweep

a mostly concurrent,low-pause collector

4 phases

  • initial mark(初始标记)
  • concurrent mark(并发标记)
  • remark(重新整理)
  • concurrent sweep(并发清除)

CMS缺点:

  • 内存碎片化(mark sweep) => 出现 无法进行升级时 会动用Serial Old 单线程进行清除
  • 浮动垃圾

解决方案

=> 降低触发CMS的阈值:

=>保持老年代有足够的空间

  • -XX:CMSInitiationgOccupancyFraction 92%

7.G1

1.9 默认

1.8 默认 PS + PO

模型改变=> 逻辑上区分新生代 老年代 物理上不区分

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aSihwoRs-1627836906272)(垃圾回收.assets/image-20210802000044893.png)]

当需要GC时,收集存活对象最少的Region

并发收集

压缩空闲空间不会延长GC的暂停时间

适用不需要实现很高吞吐量的场景,需要快的响应时间

G1回收:

YGC:Eden空间不足

FGC:Old空间不足

MixedGC(45%): GC过程相当于一个CMS. -XX:InitiationHeapOccupacyPercent,当超过阈值时, 启动MixedGC

如果产生FGC:

  • 扩内存
  • 提高CPU性能
  • 降低MixedGC触发的阈值

8.ZGC

9.Shenandoah

并发标记阶段算法:

CMS:三色标记+ Incremental Update
G1: 三色标记+ SATB(snapshot at the begining)
三色标记:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pSY9wGvT-1627836906273)(垃圾回收.assets/image-20210802003235118.png)]

漏标:

remark过程中

  1. 黑色对象指向白色对象

  2. B对象没有指向 D ,

此时 由于A已经被标记完成,不会再进行遍历,此时D漏标

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Qd5iLFMC-1627836906273)(垃圾回收.assets/image-20210802003505057.png)]

解决方案:

打破上述产生条件

1、incremental update --增量更新,关注引用增加,跟踪A指向D的引用,将黑色重新标注为灰色,下次重新扫描属性(CMS)

2、SATB (snapshot at the beginning) --关注引用删除,当B指向D消失时,把这个引用推到GC的堆栈,保证D还能被GC扫描到(G1)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值