首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >沈安多垃圾收集器装载参考屏障

沈安多垃圾收集器装载参考屏障
EN

Stack Overflow用户
提问于 2020-09-20 03:04:16
回答 1查看 256关注 0票数 0

对于那些关注Shenandoah开发的人来说,一个主要的批评是它在每次写和读时都使用了GC barriers,这不是一个大秘密:无论它是参考的还是原始的。

Shenandoah 2.0声称这不再是一个问题,它是通过所谓的负载参考屏障解决的。这到底是怎么回事?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-09-20 03:04:16

我假设读者知道什么是障碍,为什么需要障碍。非常简短的介绍here is another answer of mine on the topic

为了正确理解这一点,我们需要先看看最初的问题到底在哪里。让我们举一个相当简单的例子:

代码语言:javascript
复制
static class User {
     private int zip;
     private int age;
}

static class Holder {
    
     private User user;
     // other fields we don't care about
      
}

现在让我们想象一下这样的理论方法:

代码语言:javascript
复制
public void access(Holder holder){
     User user = holder.user;
     for(;;){ // some loop here
         int zip = user.zip;
         System.out.println(zip);

         user.age = // some value taken from the loop for example
     }
}

这样做的目的不是要显示一个正确的示例,而是要展示这样一个示例:

(user.zip;)

  • a read

写(user.age = ...)的

现在,由于Shenandoah 1.0需要在任何地方设置障碍,这段代码看起来:

代码语言:javascript
复制
public void access(Holder holder){
  User user = RB(holder).user;  
  for(;;){ // some loop here
      int zip = RB(user).zip;
      System.out.println(zip);

      WB(user).age = // some value taken from the loop for example
  }
}   

注意RB(holder).user (RB代表read barrier)和WB(user).age (WB代表write barrier)。现在假设循环是hot --你将为这么多的障碍付出代价。即使在执行循环期间没有GC活动,屏障仍然存在,并且必须有有条件地检查是否需要执行屏障的代码。

长话短说:这些障碍绝不是自由的。

为了保持堆的一致性,需要设置这些屏障,因为在疏散阶段,内存中有两个对象的副本,您需要始终保持读和写的一致性。这里一贯的意思是,在Shenandoah 1.0中,读取可能发生在“从空间到空间”或“从空间到空间”(称为“弱到空间不变”),而写入可能只发生在to-space中。

Shenandoah 2.0说,它将确保所谓的“空间不变”(相对于以前的弱不变)。基本上-它说所有的写和读将发生在/进入“到-空间”。在疏散过程中,物体有两个副本:一个在旧区域(称为“从空间”),另一个在新区域(称为“到空间”)。

它实现了这个“空间”不变与一个相当简单,但聪明的想法。它确保最初加载的对象确实从“到空间”加载,而不是在发生writes的情况下使用屏障。这是通过负载参考屏障完成的。通过重构前面的示例来理解这一点要简单得多:

代码语言:javascript
复制
  public void access(Holder holder){
      User user = LRB(holder).user;  
      for(;;){ // some loop here
          int zip = user.zip;
          System.out.println(zip);

          user.age = // some value taken from the loop for example
      }
  }

我们引入了LRB屏障,并移除了另外两个屏障。所以,当一个对象被加载时,负载引用屏障就会发生,他们称它为:在定义站点,而不是在读取或存储对象时,在它们的使用站点调用它。您可以这样想,就像在使用aloadgetField (用于引用)的地方插入了这些屏障一样。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63975139

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档