g1垃圾收集器的学习总结

最近几天学习了一下g1垃圾收集器,整理一下,方便以后得学习!

  • g1下是否还有新生代和老年代?
    有,和cms时的jvm一样,还是有新生代和老年代的,新生代也分为eden和survivor,只是他们的比例不再是固定不变的,g1会根据设定的最大停顿时间灵活的变更新生代和老年代的比例。至于为什么是这样的,请继续向下看。

  • cms只收集老年代,g1是否也是这样呢?
    g1是既能收集新生代,也能收集老年代,只是对于新生代和老年代的处理方式是不同的。在新生代的收集中,是会全部stop the world的,所以要控制新生代的大小不能太大,而老年代的收集则会经历多个阶段,其中之后几个阶段是stw的,其他的阶段是和用户线程并行执行的,所以老年代的大小可以设置的很大,并不会影响性能。g1收集新生代叫做young gc,g1收集老年代叫做mix gc,在mix gc中,都会先做一次young gc。因为young gc是会stop the world的,所以新生代不能太大,g1能控制最大停顿时间也体现在能灵活的控制新生代的大小上。

  • g1的老年代可以很大,g1在收集新生代的时候要扫描整个老年代吗?
    g1的每个region上都有一个remember set,简称RSet,这个Rset记录了其他含有指向该region中的对象的对象所在的region,Rset可以理解为是一个Map,key是region的key,value是一个数组,表示指向该region的对象所在的card page在card table中的下标(先不要管card page是啥)。在新生代中,每个region的rset中只记录老年代对其的引用,只要存在引用就认为该对象是存活的。新生代不会记录,因为在做young gc的时候整个young区的所有的region都要扫描,所以不需要在rset中记录引用关系,但是老年代的引用要记录,因为老年代不会扫描。

  • 老年代的region含有rset吗?老年代的rset是干嘛的
    老年代的region也是有的,但是老年代的rset不是存储的新生的region的引用,而是存储的老年代的存储的引用。因为在收集老年代的时候,也就是做mixed gc的时候都会先收集新生代,新生代的对象的指向关系都明确了。老年代存储的是老年代的region的指向。

  • 老年代收集的时候是会扫描所有的region的,为什么还要保存老年代的引用呢?
    因为老年代在收集的时候需要做重新标记,而重新标记的时候如果没有rset的话,就需要扫描整个老年代,所以要借助于rset,只需要扫描指定的region就能确定对象是否是存活的。
    在收集老年代的时候,可以根据设置的最大停顿时间决定要回收的region的数量,即扫描要全部扫描,但是回收的时候可以只回收一部分。

  • g1垃圾收集器中含有了rset,影响有多大,会占用多大内存呢?
    rset占用的内存比较大,大约占用10-20%的内存大小。

  • g1是如何处理新生成的数据的
    G1为每一个Region设计了两个名为TAMS(Top at Mark Start)的指针,把Region中的一部分空间划分出来用于并发回收过程中的新对象分配,并发回收时新分配的对象地址都必须要在这两个指针位置中间。G1收集器默认在这个地址中间的对象是被标记过的,认为它们是存活的,不纳入回收范围。通过这个方法解决了对象在GC过程中新分配的对象的问题,那么在GC过程中引用发生变化的问题怎么解决呢?

  • g1是如何处理漏标数据的问题的
    三色标记法中的漏标问题,因为在并发标记阶段,gc线程和应用线程是并行,假如存在a->b->c的引用,a引用了b,b引用了c,此时gc线程把a标记成了黑色,b标记成了灰色,然后此时应用线程执行了如下的代码:
    tmp = b.c;
    b.c = null;
    a.c = tmp;
    把b->c断开,并把a引用到c,此时因为a已经是黑色不再标记了,且gc线程从b也无法触达c,那么c就是白色,而被回收,但是实际不应该被回收,就导致了问题。
    G1解决三色标记算法中漏标的办法:SATB
    SATB(Snapshot At The Beginning), 在应对漏标问题时,G1使用了SATB方法来做,具体流程:
    1、在开始标记的时候生成一个快照图标记存活对象
    2、在一个引用断开后,要将此引用推到GC的堆栈里,保证白色对象(垃圾)还能被GC线程扫描到(在write barrier(写屏障)里把所有旧的引用所指向的对象都变成非白的)。配合Rset,去扫描哪些Region引用到当前的白色对象,若没有引用到当前对象,则回收。这个阶段也就是重新标记的阶段。
    所以从这里可以看出,三色标记法必须要经过两遍标记,一遍标记的话会漏标。

参考资料:
http://www.taodudu.cc/news/show-4128421.html?action=onClick
https://www.cnblogs.com/xiaojiesir/p/15598927.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
JVM (Java Virtual Machine) G1 (Garbage-First) 垃圾收集器是一种用于 Java 应用程序的垃圾收集算法。它是自JDK 7u4版本后引入的一种全新的垃圾收集器G1垃圾收集器的设计目标是为了解决传统的分代垃圾收集器可能遇到的一些问题,如停顿时间长、内存碎片化等。它采用了一种基于区域的垃圾收集方式,可以将内存划分为多个大小相等的区域,每个区域可以是Eden、Survivor或Old区。 G1垃圾收集器的工作原理如下: 1. 初始标记(Initial Mark):标记所有从根对象直接可达的对象。 2. 并发标记(Concurrent Mark):在并发执行程序的同时,标记那些在初始标记阶段无法访问到的对象。 3. 最终标记(Final Mark):为并发标记阶段中发生改变的对象进行最终标记。 4. 筛选回收(Live Data Counting and Evacuation):根据各个区域的回收价值来优先回收价值低的区域。 G1垃圾收集器具有以下特点: - 并发执行:在执行垃圾收集过程时,尽可能减少应用程序的停顿时间。 - 分区回收:将整个堆划分为多个区域,可以根据需要优先回收垃圾较多的区域,从而避免全堆回收带来的长时间停顿。 - 内存整理:G1垃圾收集器会对内存进行整理,减少内存碎片化,提高内存利用率。 需要注意的是,G1垃圾收集器并不适用于所有情况。在特定的场景下,如大堆情况下的长时间运行、对延迟要求非常高的应用等,可能需要考虑其他垃圾收集器的使用。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值