Eug*_*ene 3 java garbage-collection jvm shenandoah
在Shenandoah 1.0每个对象中都有一个额外的头文件——称为forwarding pointer. 为什么需要它,导致它被消除的原因是什么Shenandoah 2.0?
首先,每个 java 对象都有两个头文件:klass和mark. 它们一直存在于每个实例中(例如,它们可以稍微改变 JVM在内部使用最近的 JVM 处理其标志的方式)并且出于各种原因使用(将在答案中仅详细介绍其中一个) )。
这个答案的第二部分forwarding pointer字面上需要 a 。将需要在这两个和的(虽然读可以跳过某些字段类型的障碍-不细讲)。用非常简单的话来说,它极大地简化了并发复制。正如那个答案中所说,它允许自动切换到对象的新副本,然后同时更新所有引用以指向该新对象。forwarding pointerread barrierwrite barrierShenandoah 1.0forwarding pointer
事情已经改变了一个位Shenandoah 2.0,其中“以空间不变的”到位:这意味着所有的写入和读取完成后通过to-space。这意味着一个有趣的事:曾经的to-space副本成立,from-copy从未使用过。想象一下这样的情况:
refA refB
| |
fwdPointer1 ---- fwdPointer2
|
--------- ---------
| i = 0 | | i = 0 |
| j = 0 | | j = 0 |
--------- ---------
Run Code Online (Sandbox Code Playgroud)
在Shenandoah 1.0某些情况下,通过读取refA可以绕过屏障(根本不使用它)并且仍然通过from-copy. final例如,这对于字段是允许的(通过特殊标志)。这意味着即使to-space副本已经存在并且已经有对它的引用,仍然可能有读取(通过refA)会转到from-space副本。在Shenandoah 2.0这被禁止。
这些信息以一种相当有趣的方式被使用。Java 中的每个对象都对齐到 64 位 - 这意味着最后 3 位始终为零。所以,他们放弃了forwarding pointer并说:如果mark单词的最后两位是11(这是允许的,因为没有其他人以这种方式使用它)-> 这是 a forwarding pointer,否则to-space副本确实存在并且这是一个普通的标题。您可以在此处看到它的运行情况,并且可以在此处和此处跟踪屏蔽。
它曾经是这样的:
| -------------------|
| forwarding Pointer |
| -------------------|
| -------------------|
| mark |
| -------------------|
| -------------------|
| class |
| -------------------|
Run Code Online (Sandbox Code Playgroud)
并转变为:
| -------------------|
| mark or forwarding | // depending on the last two bits
| -------------------|
| -------------------|
| class |
| -------------------|
Run Code Online (Sandbox Code Playgroud)
所以这是一个可能的场景(class header为简单起见,我将跳过):
refA, refB
|
mark (last two bits are 00)
|
---------
| i = 0 |
| j = 0 |
---------
Run Code Online (Sandbox Code Playgroud)
GC开始。引用的对象refA/refB是活着的,因此必须被疏散(据说它在“集合集”中)。首先创建一个副本并原子地mark引用该副本(最后两位也被标记为11现在使其成为 aforwardee而不是 a mark word):
refA, refB
|
mark (11) ------ mark (00)
|
--------- ---------
| i = 0 | | i = 0 |
| j = 0 | | j = 0 |
--------- ---------
Run Code Online (Sandbox Code Playgroud)
现在其中一个mark words 有一个位模式(以 结尾11),表明它是转发者而不是标记词。
refA refB
| |
mark (11) ------ mark (00)
|
--------- ---------
| i = 0 | | i = 0 |
| j = 0 | | j = 0 |
--------- ---------
Run Code Online (Sandbox Code Playgroud)
refB可以同时移动,所以那么refA,最终没有对from-space对象的引用,它是垃圾。如果需要,这就是mark word作为 的方式forwarding pointer。
| 归档时间: |
|
| 查看次数: |
92 次 |
| 最近记录: |