IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> JVM-三色标记算法 -> 正文阅读

[数据结构与算法]JVM-三色标记算法

JVM-三色标记算法

三色标记算法是一种垃圾回收的标记算法。它可以让JVM不发生或仅短时间发生STW(Stop The World),从而达到清除JVM内存垃圾的目的。JVM中的CMS、G1垃圾回收器 所使用垃圾回收算法即为三色标记法。

三色标记过程:

黑色:代表该对象以及该对象下的属性全部被标记过了。(程序需要用到的对象,不应该被回收)

灰色:对象被标记了,但是该对象下的属性未被完全标记。(需要在该对象中寻找垃圾)

白色:对象未被标记(需要被清除的垃圾)

在这里插入图片描述

三色标记存在的问题:

对象漏标:

在这里插入图片描述

如果已经被C已经被标记为黑色了,因为是并发标记,此时可能会有线程在C中引用D。此时由于C已经被标记为黑色,不会再扫描D。D会被认为需要回收,此问题会导致系统出问题。

CMS 和 C1采用了两种方式来解决上面的问题

CMS(Concurrent Mark Swap):

以获取最短回收停顿时间为目标的收集器。基于标记-清除算法实现。

运行过程:
在这里插入图片描述

由初始标记->并发标记->再次标记->并发清理实现

并发清理时,直接删除掉标记阶段判断为垃圾的对象,因为不需要移动存活的对象,所以可以与用户线程同时并发。

如何解决漏标

在应对漏标问题时,CMS使用了增量更新的方法(Increment Update)

当未被标记的对象被重新引用后,引用它的对象如果是黑色的话,那么会将颜色置为灰色,在二次标记的时候让GC线程继续标记它的属性对象

CMS的缺点:

1、浮动垃圾:CMS采用了标记-清除的算法,最终必然产生许多的内存碎片,当到达一定数量时,CMS无法清理这些碎片,会启动Serial Old垃圾回收器(标记整理算法)来清理这些垃圾。serial Old是单线程操作进行垃圾清理,效率很低。

针对上述问题 可以考虑采用Mark-Sweep-Compact压缩算法,减少垃圾碎片

-XX:+UseCMSCompactAtFullCollection  开启CMS的压缩
-XX:CMSFullGCsBeforeCompaction 默认为0,指经过多少次CMS FullGC才进行压缩

2.还有一种情况会触发SerialOld ,在使用CMS进程并发清理内存是可能发生OOM的问题。不得不进行SerialOld,针对这个问题可以降低触发CMS GC的阈值,使浮动垃圾不那么容易占满老年代。

-XX:CMSInitiatingOccupancyFraction 92% 可以降低这个值,让老年代占用率达到该值就进行CMS GC

G1(Garbage First)

G1(Garbage First)物理内存不再分代,而是由一块一块的Region组成,但是逻辑分代仍然存在。G1不再坚持固定大小以及固定数量的分代区域划分,而是把连续的Java堆划分为多个大小相等的独立区域(Region),每一个Region都可以根据需要,扮演新生代的Eden空间、Survivor空间,或者老年代空间。收集器能够对扮演不同角色的Region采用不同的策略去处理,这样无论是新创建的对象还是已经存活了一段时间、熬过多次收集的旧对象都能获取很好的收集效果。

Region中还有一类特殊的Humongous区域,专门用来存储大对象。G1认为只要大小超过了一个Region容量一半的对象即可判定为大对象。每个Region的大小可以通过参数-XX:G1HeapRegionSize设定,取值范围为1MB~32MB,且应为2的N次幂。而对于那些超过了整个Region容量的超级大对象,将会被存放在N个连续的Humongous Region之中,G1的大多数行为都把Humongous Region作为老年代的一部分来进行看待

在这里插入图片描述

CardTable

在YGC是,我们在对一个对象是否被引用的过程,如果这个对象被Old区的对象所引用,那么我们就需要扫描整个Old区,这显然会耗费很大的时间。所以JVM设计了CardTable,将Old区分为一个一个Card,一个Card有多个对象;如果一个Card中的对象有引用指向Young区,则将其标记为Dirty Card,下次需要进行YoungGC时,只需要去扫描Dirty Card即可。

Card Table在底层数据结构以BitMap实现

RSet(Remembered Set)

是辅助GC过程的一种结构,典型的空间换时间工具,和Card Table有些类似。

后面说到的CSet(Collection Set)也是辅助GC的,它记录了GC要收集的Region集合,集合里的Region可以是任意年代的。

在GC的时候,对于old->young和old->old的跨代对象引用,只要扫描对应的CSet中的RSet即可。逻辑上说每个Region都有一个RSet,RSet记录了其他Region中的对象引用本Region中对象的关系,属于points-into结构(谁引用了我的对象)。

而Card Table则是一种points-out(我引用了谁的对象)的结构,每个Card 覆盖一定范围的Heap(一般为512Bytes)。G1的RSet是在Card Table的基础上实现的:每个Region会记录下别的Region有指向自己的指针,并标记这些指针分别在哪些Card的范围内。这个RSet其实是一个Hash Table,Key是别的Region的起始地址,Value是一个集合,里面的元素是Card Table的Index。每个Region中都有一个RSet,记录其他Region到本Region的引用信息;使得垃圾回收器不需要扫描整个堆找到谁引用当前分区中的对象,只需要扫描RSet即可。

新生代与老年代的比例

5% - 60%,一般不使用手工指定,因为这是G1预测停顿时间的基准,这地方简要说明一下,G1可以指定一个预期的停顿时间,然后G1会根据你设定的时间来动态调整年轻代的比例,例如时间长,就将年轻代比例调小,让YGC尽早行

如何解决漏标:

在应对漏标时,采用了SATB (snapshot at the beginning)

  • 在标记开始的时候成成一个快照图标记存活对象
  • 在一个引用断开后,要将此引用推到GC的堆栈中,保证对象还能被GC线程扫描到(通过在 wirte barrier 里把所有旧的引用所指向的对象都变成非白的)
  • 配合Rset,去扫描哪些Region引用到当前的白色对象,若没有引用到当前对象,则回收

SATB效率高于增量更新的原因

因为SATB在重新标记环节只需要去重新扫描那些被推到堆栈中的引用,并配合Rset来判断当前对象是否被引用来进行回收;

并且在最后G1并不会选择回收所有垃圾对象,而是根据Region的垃圾多少来判断与预估回收价值(指回收的垃圾与回收的STW时间的一个预估值),将一个或者多个Region放到CSet中,最后将这些Region中的存活对象压缩并复制到新的Region中,清空原来的Region

G1会不会进行FullGC?

会,当内存空间不足就会进行FullGC。

解决方案:

  • 加大内存

  • 提高CPU性能,加快GC回收速度

  • 降低MixedGC 触发阈值,让Mixed GC提早发生(默认45%)

    MiexedGC 过程相当于一个CMS.

    -XX:InitiationHeapOccupacyPercent,当超过阈值时, 启动MixedGC
    

针对上面的描述我们也可以进行下概述

CMS和G1有什么区别

  • 作用范围

    CMS针对老年代。可以配合Serial 或 Parallel New这些新生代的垃圾回收器。如果碎片过多,老年代会使用Serial Old进行垃圾回收

    G1则是针对 老年代和新生代

  • 停顿时间

    CMS以最小停顿时间为目标

    G1可以预测垃圾回收时间

  • 垃圾碎片

    CMS收集器使用标记-清除算法进行垃圾回收,容易产生碎片

    G1由于使用了Region的概念,降低了内存碎片

  • 大对象处理
    除了上面优点之外,还有一个优点,那就是对大对象的处理。在CMS内存中,如果一个对象过大,进入S1、S2区域的时候大于改分配的区域,对象会直接进入老年代。G1处理大对象时会判断对象是否大于一个Region大小的50%,如果大于50%就会横跨多个Region进行存放

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-10-21 12:38:31  更:2021-10-21 12:41:06 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 8:59:18-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码