[Java JVM] Hotspot GC研究- 什么是GC Root

GC Root

GC Root全称是garbage collection root, 即垃圾回收的根. 回到我们的葡萄比喻上来, 也就是一串葡萄的柄. 实际上JVM中的GC Root不只一个, 也就是多个这样的 “柄”.

来看看hotspot网站的解释:

garbage collection root

A pointer into the Java object heap from outside the heap. These come up, e.g., from static fields of classes, local references in activation frames, etc.

官网的解释是由heap外部指向heap内的对象的指针, 比如class的静态字段, 活跃栈帧里的本地引用等. 这里有点小疑问, 从代码上来看, 静态字段也是存在于heap对象(Class对象)中的, 这样来看, 按照heap外指针的定义来解释好像不太妥当. 可以先不关注这个问题, 等会我们从代码上来直观感受一下.


为什么需要GC Root

这个说法可能听起来有点奇怪, 因为GC Root的存在是客观的, 并不是因为需要, 这里的意思更多的是为什么要单独提出这么一个概念. 前面介绍过, 对象之间的相互引用会形成一个图(graph), 而要遍历存活的对象, 必须从一些点出发, 这些点, 就是GC Root了.

可能提到管理对象的存活很多人(包括我)第一次接触到的概念都是引用计数的方式, 这种方式很直接也很好理解, 被引用计数+1, 减少引用计数-1, 当计数是0的时候, 说明没人可以再访问, 于是释放. 具体的细节我研究的也不多, 不过大家应该都知道这种方式没法很好的解决循环引用的问题. 虽然形如 A <-> B这种形式是可以方便检测出来的, 只要记住遍历过的点, 深度往下遍历, 如果发现曾在访问过的点中的对象, 则代表出现了回路. 不过有个不确定的事情就是A -> B -> … ->Z -> A这种绕了一大圈又回到起始点的引用环, 可以想象如果中间有100000个对象, 最后形成了一个回路, 这个检测是很麻烦的.

而通过GC Root的扫描遍历则不会有这个问题, 还是拿葡萄举例, 想象一下, 如果一串葡桃里由几个落单了, 虽然落单的葡桃里有一个挂着另外一个, 但是通过柄(Root)把他们提起来的时候, 他们自然就掉下来了, 不会被认为是存活的, 这是基于GC Root扫描的一个好处. 当然, 这种方式也是有代价的, 那就是要知道存活的对象, 必须扫描整个heap, 当heap很大的时候, 这个时间是比较久的. 为了缓解这个问题, hotspot想了一些办法, 比如分代收集, 不到万不得已不扫描整个heap.


从代码来看GC Root

void GenCollectedHeap::process_roots(StrongRootsScope* scope,
                                     ScanningOption so,
                                     OopClosure* strong_roots,
                                     OopCl
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值