0

标题几乎说明了一切——这些自我修复障碍是什么?为什么它们在雪兰多 2.0 中很重要?

4

1 回答 1

2

这个解释将搭载我试图提出的一些答案的第一部分第二部分Shenandoah 2.0

要真正回答这个问题,我们需要看一下它load reference barrier是如何实现的以及GC cycle一般是如何起作用的。

当某个GC cycle触发时,它首先选择垃圾最多的区域;即:集合集中的对象很少(这在未来很重要)。理解这个主题的最简单方法是通过一个例子。假设这是一个现在存在于某个区域的方案:

refA refB            
    |               
---------
|  mark |                    
---------          
| i = 0 |          
| j = 0 |          
--------- 

该区域中存在一个对象,并且有两个指向它的引用:refArefBGC启动并选择该区域进行垃圾收集。同时,应用程序中有活动线程尝试通过refA和访问此对象refB。由于这个物体alive在某个时候需要被疏散到一个新的区域(mark-compact阶段的一部分)。

所以:GC活跃的,同时,我们通过refA/refB. 当我们做这个阅读时,我们会踩到load-reference-barrier,执行到这里。注意它内部有一些“过滤器”(通过一堆if/else语句)。具体来说:

  • 它检查“疏散当前是否正在进行”。这是通过在疏散首次开始时设置的线程本地标志来完成的。让我们假设答案是:是的。

  • 它检查我们当前正在操作的对象是否在“集合集”中。这意味着它当前被标记为活动的。让我们假设这也是“是”。

  • 最后一项检查是确定该对象是否已经“复制”到不同的区域(它已被疏散)。让我们假设这个问题的答案是“否”,即 : obj == fwd

在这个时间点,发生了一些事情。首先创建一个副本并mark 成为转发者

    refA refB            
        |               
 --------------      ---------
 |  forwardee | ---- | mark |            
 --------------      ---------    
    | i = 0 |        | i = 0 |  
    | j = 0 |        | j = 0 |  
    ---------        ---------

只有在代码的后面,才会refA更新refB以指向的(复制的)对象。但这意味着一件有趣的事情。这意味着直到refArefB实际指向新对象,即它们当前指向的对象,位于“集合集”中。因此,如果 GC 处于活动状态并且即使forwardee已经建立,load-reference-barrier仍然需要做一些工作。

所以背后非常聪明的人Shenandoah说:为什么不在forwardee建立之后立即更新那里的参考资料(或者当forwardee其他参考资料已经知道时)?而这正是他们所做的。

假设我们回到最初的绘图:

refA refB            
    |               
---------
|  mark |                    
---------          
| i = 0 |          
| j = 0 |          
--------- 

再次,我们“启用”所有过滤器:

  • 有一个线程通过refA

  • GC 处于活动状态

  • 后面的物体refArefB活的。

这就是“自我修复障碍”会发生的事情:

       refB             refA
        |                |
 --------------      ---------
 |  forwardee | ---- | mark |            
 --------------      ---------    
    | i = 0 |        | i = 0 |  
    | j = 0 |        | j = 0 |  
    ---------        ---------

区别很明显:当场refA通过 , 移动到指向新对象。CAS如果要通过再次读取refA(GC 仍然处于活动状态),这将导致更快的加载引用屏障执行。为什么?因为refA指向不在“集合集”中的对象。

但这也意味着,如果我们阅读 viarefB并看到fwd != obj- 代码可以执行相同的技巧并更新refB原地,在第一次阅读发生时 via refB

据熟悉此事的人说,这提高了性能,我相信他们。

于 2020-09-29T17:27:59.643 回答