JVM的GC算法

并行GC 和 并发GC
G1GC(Garbage First Garbage Collection)
1.实时性的区分
硬实时性 软实时性 个人理解硬实时性需要在deadline之前完成 往往硬实时性需要快速响应 而软实时性可以在deadline之后也能完成 但是呢 它的频率势必会遭到限制
Tips:deadline可以由开发者人为设置
2.可预测性
相比于高速性 GC更看重它的可预测性 例如在开发中 高并发的处理中 我们知道了某个线程可能会有deadline了 那么最好的做法肯定还是提前预测 凡是预则立 不预则废 对于这种危机公关意识 我们说不仅中国人会将它考虑进去 Java的设计者高斯林也在GC中进行了实现
3.G1GC的实时性
G1GC具有的是软实时性 它具有以下两个功能
1)设置期望暂停时间(最后期限)
Tips:用户自定义mutator暂停时间的功能,尽力保证处理不超过该暂停时间(mutator一般指应用程序)
2)可预测性
预测下一次GC导致暂停多长时间的功能 根据预测结果G1GC会通过延迟G C.拆分GC目标对象等来达到mumator的暂停时间 以实现软实时性
4.出现背景
此前出现的应用程序主要采用增量GC或并发GC来缩短最大暂停时间 很容易导致吞吐量下降 除此之外 GC可能会有mutator长时间停止的风险
5.堆结构
6.执行过程
G1GC的两个功能:
1)并发标记
并发标记基本和mutator并发执行,针对区域内所有存活对象进行标记 由并发标记线程来执行
2)转移
释放堆中的死亡对象所占的空间
Tips:并发标记和转移在处理上是相互独立的
第二节 并发标记
1.什么是并发标记
在简单标记中,所有可从根直接触达的对象都会被添加标记。带标记的是存活对象,不带标记的是死亡对象。
Tips:并发标记不是直接在对象上添加标记,而是在标记位图上添加标记。
2.标记位图
将用于标记的比特值等信息单独拿出来放到其他地方,用来匹配对应的对象。
指在堆的一个区域,每个区域都带有两个标记位图:next和prev。next是本次的标记位图,prev是上次的标记位图,保存了上次标记的结果。
3.执行步骤
1)初始标记阶段(暂停mumator的运行,标记可由根直接引用的对象)
2)并发标记阶段(标记扫描)
3)最终标记阶段(暂停处理)
4)存活对象技术(对被标记对象计数)
5)收尾工作(暂停处理)
在2 3 4 5这四个步骤一般都会开启多个线程,并行的执行任务。
4.详细步骤
1)初始标记阶段
对可由根直接引用的对象进行标记的过程叫做根扫描。等所有区域的标记位图都创建完成之后,就可以开始进行根扫描了。为了防止在根扫描的过程中根被修改,在这个过程中mumator是暂停执行的。如果一个对象本身被标记了,但其子对象并没有被扫描,我们就称它为未扫描对象。
当完成根扫描后,mutator会再次开启执行,GC处理也会进入下一个阶段。
2)并发标记阶段
Tips:GC线程继续扫描在初始标记阶段被标记过的对象,完成对大部分存活对象的标记。
重要特点是:GC线程和mutator是并发执行的。mutator在执行过程中可能会改变对象之间的引用关系,所以如果只采用一般的标记方法,可能会发生“标记泄露”。
在垃圾收集(Garbage Collection)的过程中,标记遗漏(Marking Omission)是指垃圾收集器在标记阶段中漏掉了某些对象,导致这些对象没有被正确地标记为存活对象,进而被错误地回收。

标记遗漏可能会导致以下问题:

  1. 内存泄漏:被错误地回收的对象实际上仍然被程序使用,但由于标记遗漏,垃圾收集器将其判断为垃圾并回收,导致内存泄漏问题。
  2. 程序错误:如果被错误回收的对象在后续的程序执行中仍然被引用,那么程序可能会出现错误、崩溃或不可预测的行为。

标记遗漏的原因可能包括:

  1. 并发标记问题:在并发标记的情况下,垃圾收集器可能无法准确地追踪所有的对象,从而导致标记遗漏。
  2. 跨代引用问题:如果一个对象在标记阶段被标记为存活对象,但在后续的标记阶段中被其他代的对象引用,那么可能会发生标记遗漏。
  3. 隐式引用问题:某些对象可能没有明确的引用关系,但实际上仍然被程序使用,这种情况下垃圾收集器可能无法正确地标记这些对象。

为了避免标记遗漏,垃圾收集器需要具备准确标记对象的能力,并且需要考虑并发标记和跨代引用等特殊情况。此外,程序开发人员也可以通过合理的内存管理和资源释放来减少标记遗漏的可能性。
3)最终标记阶段
该阶段的处理是暂停处理,需要暂停mutator的运行。
本步骤结束后,所有的存活对象都已被标记。此时所有不带标记的对象都可以判定为死亡对象。因为SATB本地队列中的数据会被mutator操作,所以本步骤不能和mutator并发执行。
4)存活对象技术
这个步骤会扫描各个区域的标记位图next,统计区域内存活对象的字节数,然后将其存入区域内的next_marked_bytes中,初始值为0。
计数处理和mutator是并发执行的,但是在计数过程中操作的对象可能会被转移的记忆集合线程使用,因此需要先停掉记忆集合线程。
5)收尾工作
收尾工作所操作的数据有些是和mutator共享的,因此需要暂停mutator的运行。
在扫描过程中还会计算每个区域的转移效率,并按照该效率对区域进行降序排列。
转移效率指的就是转移一个字节所需要的时间
公式:死亡对象的字节数/转移所需时间
转移
1.什么是转移
将所选区域内的所有存活对象都会被转移到空闲区域,则被转移区域内就只剩下了死亡对象。重置之后,该区域就会变成为空闲区域,能够再次利用。
2.转移专用记忆集合
可以通过根和并发标记和转移专用记忆集合来发现对象。G1GC通过卡表来实现转移专用记忆集合。卡表是由元素大小为1B的数组实现的。卡表的元素称为卡片。卡片的种类很多,我们主要关注的是脏卡片和净卡片。
3.转移专用写屏障
当对象的域被修改的时候,被修改对象所对应的卡片会被转移专用写屏障记录到转移专用记忆集合中。需要提一下的是,每个mutator线程都持有一个名为转移专用记忆集合日志的缓冲区,其中存放的是卡片索引的数组。
4.转移专用记忆集合维护线程
转移专用记忆集合维护线程是和mutator并发执行的线程,它的作用是基于转移专用记忆集合日志的集合,来维护转移专用记忆集合。
5.热卡片
6.执行步骤
7.细节
1)选择回收集合
2)根转移
3)转移
8.标记信息的作用

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值