GC how to deal with object references

doubt:

When studying the GC found that both Mark and Copy, or Mark-Sweep-Compactalgorithm, to be 移动对象, this will inevitably lead to the object 内存地址changed, so after the move, the object is how to find the address of the new memory heap objects?

Does every move an object, you will find and update all references to the object of reference?

Garbage collection algorithms: https://plumbr.io/handbook/garbage-collection-algorithms

Sun HotSpot object access method:

"In-depth understanding of the Java Virtual Machine," second edition, Chapter 2 2.3.3 对象的访问定位mentions object access mainstream there are two ways:

  • Handle
  • Direct pointer *

HotSpot is used 直接指针to locate the object.

Handle:

If you use the handle to access, then the Java heap will be divided into a block of memory to handle as the handle address pools, is stored in the reference object, and the handle contains specific information about the type of data object instance data with each.

Use the handle to access the greatest benefit is that reference is stable in storage handler address, the object is moved ( garbage collection will only change the instance data pointer in the handle when moving objects are very common behavior), while the reference itself does not need modify.

img

Direct pointers:

If you use direct access pointer, then the layout of the Java object it is necessary to consider the relevant information on how to access the data type of placement, and direct reference is stored in the object address.

Direct access manner pointer biggest advantage is speed, it saves time overhead of a pointer is positioned due to access objects in Java very frequently, so after such expenses add up to a very significant point is cost.

就本书讨论的主要虚拟机 Sun HotSpot 而言,它就是使用第二种方式进行对象访问的,但从整个软件开发的范围来看,各种语言和框架使用句柄访问的情况也十分常见。

GC 时如何处理对象引用:

在 HotSpot 里 Java 对象的对象头存在两个字段(大小为2 word):

_mark  // mark word
_klass // klass pointer

mark word 用于存储多种信息,例如对象的 identity hash code、锁状态、full gc 时 mark 状态等等。

在 GC 时,如果一个对象被拷贝了,那么该对象头中 mark word 的 forwarding pointer 就会指向拷贝后的对象的地址。

Yong GC 类算法流程:

首先从 GC Roots 和 Old -> Young 的 Card Table(即存储了老年代对象与新生代对象之间的引用关系)出发,扫描追踪整个新生代的对象关系图。注意,在扫描过程中如果碰到指向老年代对象的引用,则停止这一路径的扫描。同时每扫描到一个对象,如果它是第一次被标记的话,我们就会将其拷贝到 survivor 区,或者晋升到老年代,并且在原对象位置的 mark word 域填上它的新地址 forwarding pointer。这样,如果原对象同时被两个以上的 reference 指向,那么在追踪过程中,别的 reference 还是有机会碰到此对象的原位置,然后发现它已经被标记过了,所以只需要通过 mark word 域的 forwarding pointer 更新 reference 值即可。

使用这类算法的有 Serial Young GC(即DefNew)、Parallel Young GC、ParNew,以及 G1 GC 的 Young GC & Mixed GC。

只需要一次遍历就可以完成对对象的拷贝和 reference 的更新。

Full GC 类算法流程:

有4个主要步骤:

1 标记:

  • 直接从 GC Roots 出发,扫面一遍整个堆(有时可以加上 metaspace),找到所有活的对象。

2 计算新地址:

  • 既然已知所有活的对象,那么就能够准确计算出它们在 compaction 后的新地址,然后将计算好的新地址保存到 mark word 域中。

3 更新 reference:

  • 更新所有活对像中指向其他对象的 reference 的值,让它们指向步骤 2 中计算好的新地址(从 mark word中读取)。

4 复制对象到新地址:

  • 将对象复制到步骤 2 计算的新地址。

使用这类算法的有 Serial Old GC、PS MarkSweep GC、Parallel Old GC、Full GC for CMS 和 Full GC for G1 GC。

参考:

[StackOverFlow] how a copying collector deals with this problem : https://stackoverflow.com/questions/9465767/if-the-jvm-keeps-moving-objects-around-when-it-does-gc-how-does-it-resolve-refe

[知乎] 关于Copy与Compaction两种算法如何处理对象地址: https://www.zhihu.com/question/42181722

[知乎] Copy GC的基本原理: https://zhuanlan.zhihu.com/p/28197216

[知乎] Mark & Compaction GC的基本原理: https://zhuanlan.zhihu.com/p/30797760

[Denver] of the JVM card table (the Table Card): https://juejin.im/post/5c39920b6fb9a049e82bbf94

Guess you like

Origin www.cnblogs.com/demojie/p/12286037.html