对于JAVA GC的理解

GC root

所谓“GC roots”,或者说tracing GC的“根集合”,就是一组必须活跃的引用。

注意,是一组必须活跃的引用,不是对象。

而且对于年轻代GC,GC ROOT必须是年轻代对象的引用。
对于老年代GC, GC ROOT必须是老年代对象的引用。

GC root枚举

以young gc为例(old gc同理):

在进行gc trace之前,必须对gc root进行枚举,保证年轻代里所有存活的对象都能被标记到。

  1. JVM使用OoMap记录了负责记录堆外对堆内的引用,遍历OoMap,将其中属于年轻代的引用设置为GC root。

  2. JVM再遍历老年代中的所有对象(先不考虑Remember Set),将老年代所持有的年轻代对象的引用也设置为GC root。

为什么要遍历老年代的所有对象,而不直接使用OoMap中的老年代引用进行dfs搜索?

OoMap中记录了所有堆外对堆内的引用,包括老年代和年轻代,在GC root枚举时,我们忽略了老年代引用。但是为什么不直接使用老年代引用进行dfs搜索,找出相关的跨代引用呢?这不比遍历老年代所有对象更快速吗?

要回答这个问题,要理解跨代引用的两种方式:

  1. OoMap -》老年代对象 -》年轻代对象
  2. OoMap -》年轻代对象1 -》老年代对象 -》年轻代对象2

我们知道在GC Trace的时候,如果碰到老年代的对象,则停止trace,所以减少了老年代内存空间的扫描。

  1. 所以对于第1中方式的跨代引用,老年代对象在OoMap中记录了,所以利用OoMap中的老年代对象进行dfs搜索跨代引用,是可以搜索到对应的年轻代,将其引用加入GC ROOT。

  2. 但是对于第2种方式的跨代引用,OoMap中没有记录老年代对象,所以无法找到对应的年轻代对象2,无法将其引用加入GC ROOT。虽然年轻代对象1是GC root,但是其在trace的过程中,搜索到老年代对象时就停止,所以年轻代对象2无法被标记。

由上述我们可以知道,必须对老年代的所有对象进行遍历,判断其是否有跨代引用,但是这同时也让一个垃圾内存无法回收,比如老年代的垃圾对象具有跨代引用,那它指向的年轻代对象也无法回收。

所以为了不遍历老年代的所有对象,使用了Remember Set记录老年代对年轻代的引用,减少了扫描的范围。

但是对于CMS这种old gc的实现,由于其没有实现年轻代-》老年代的Remember Set,所以其必须要遍历年轻代的所有对象,寻找跨代引用,将其加入GC ROOT。

GC Trace

在这里插入图片描述

GC优化

GC优化的核心思路在于:尽可能让对象在新生代中分配和回收,尽量避免过多对象进入老年代,导致对老年代频繁进行垃圾回收,同时给系统足够的内存减少新生代垃圾回收次数。

young gc频繁:

  1. young gc后年轻代对象很少:
    说明内存中短期对象很多,增大年轻代,young GC时间更多取决于GC后存活对象的数量,而非Eden区的大小。
  2. young gc后年轻代对象很多:
    说明内存中长期对象很多,young gc无法对其收集,可以减少对象晋升年龄(动态年龄判断有相似的作用),将长期对象早点进行老年代,年轻代供短期对象使用。也可降低年轻代,增加老年代的大小。

full gc频繁:

  1. full gc后老年代对象很少:
    说明老年代进入了大量短期对象,所以增大年轻代/Survivor空间。
  2. full gc后老年代对象很多:
    系统中具有大量的长期对象,降低年轻代,增加老年代的大小,或者增加整体的内存大小。

参考:
http://ericfu.me/g1-garbage-collector
https://segmentfault.com/q/1010000040841261
https://www.zhihu.com/question/53613423/answer/135743258
https://blog.csdn.net/wtopps/article/details/109186517
https://tech.meituan.com/2017/12/29/jvm-optimize.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值