java - FIXME : NYI in MutableCallSite. syncAll 是否意味着尚未实现?

标签 java android concurrency jvm

java.lang.invoke有两个有趣的结构,MutableCallSiteSwitchPoint .它们被描述为提供了一种更改其目标的方法(对于 MutableCallSite 可以更改为任意不同的目标,或者 SwitchPoint 可以更改为预定义的无效时目标),其他线程保证可以获取更新,但是当 MCS 或 SP 未更改时,减少了使用 MCS 或 SP 的开销(与每次使用时检查同步效果相比,减少了)。 SwitchPoint文档说它可以建立在 MutableCallSite ,并且在 GitHub 上的 OpenJDK 源代码中,它是。所以寻找魔法的地方是MutableCallSite.syncAll .
the source for that method ,魔法似乎有三个步骤:

  • 第 1 步是 lazySet (setRelease 的 JMM 影响)在私有(private) AtomicInteger 上没有其他线程会阅读;
  • 第 2 步查看所有通过的 MutableCallSite确认无的引用为空;
  • 第 3 步是注释:// FIXME: NYI

  • 对于未经训练的人来说,该评论似乎还有很多工作要做。 ;)
    似乎 Android 的开发人员看到了该评论和 removed the method from Android因为他们不想宣传未实现的方法(即使没有 MutableCallSitesyncAll 似乎不是一个有用的构造)。他们是对的吗?
    另一方面,它似乎真的不太可能如此明显地错过它的功能。它从 Java 7 开始就出现在 Java 中,而且像 Nashorn 和 JRuby 这样的重要项目已经大量使用了MutableCallSite。和 SwitchPoint .我没有偶然发现任何关于他们因此而被打破的评论。
    更重要的是,我知道 Java 类库中的某些实现可能看起来不完整,因为部分魔法是由 JVM 实现提供的。这似乎是可能发生这种情况的一个主要例子,但我无法找到详细信息。
    有人知道细节吗?最好知道真正的可靠行为是什么。 syncAll javadoc 一开始听起来很有希望。释义:
  • 其效果是强制每个调用站点目标的所有 future 读者接受最近存储的值
  • 它可能(可能??)阻塞,直到所有读者(以某种方式)解除所有先前版本的缓存
  • 阅读器线程可能会在 syncAll 之前观察目标的先前版本。调用返回。 (这是否意味着在 syncAll 调用返回后他们可能不会这样做?如果是这样,那是否意味着 #2 真的比“可能”更强大?)
  • 它“可能很昂贵”(作为 getTarget 便宜的权衡;这是神奇的部分)。

  • 但稍后在同一个 javadoc 中,深入研究 JMM 细节,它说“如果(其他线程)T 在 volatile 写入之后执行同步操作 A”......那么它必须看到更新的目标。
    这听起来有点……不那么健壮。
    这一切是否都基于一些 JVM 实现知识,这些知识对 syncAll 之后可以花费的时间设置了上限?返回?如果是这样,可以说明该上限吗?
    如果确实没有遗漏任何东西并且事情像宣传的那样工作,是否值得删除 // FIXME: NYI在源代码中(也许用真正发生的事情的解释来代替它)?
    更多信息:earlier version of this question发表于 mlvm-dev列出但没有吸引任何答案。

    最佳答案

    boneill 的评论以及 Remi Forax 的链接并发兴趣邮件列表响应似乎包含了答案。 MutableCallSite.syncAll方法确实没有做宣传的事情,但行为最终是足够的,因为 MutableCallSite.setTarget做的比宣传的要多。所以在方案中

    for ( i = 0; i < sites.length; ++ i )
      sites[i].setTarget(newTargets[i]);
    MutableCallSite.syncAll(sites);
    
    发生必要的同步;只是大部分工作发生在 syncAll 之前。 .同样,
    SwitchPoint.invalidateAll(switchpoints);
    
    (就像上面一样,它被实现为一个循环,触及每个 MutableCallSite 底层的 SwitchPoint )也会发生必要的工作。
    然而,这个部分实现的方案并不完美:将繁重的工作从 syncAll 移开进入 setTarget看起来它牺牲了支付 syncAll 的广告利益更新 n 个调用站点目标后只需花费一次。在这个实现中,该成本(mark_dependent_nmethodsdeoptimize_all_marked 通过与所有线程握手)发生 n 次,但每次只处理一个 CallSite 的依赖关系。 . SwitchPoint.invalidateAll 也是如此数组 n SwitchPoint s。
    我不知道为什么它自 Java 7 以来一直处于这种开发状态,但如果它按照最初记录的方式实现,看起来可能会有很好的性能提升空间。

    关于java - FIXME : NYI in MutableCallSite. syncAll 是否意味着尚未实现?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70163017/

    相关文章:

    java - java 如何从实例字段获取对象?

    java - 使用 PATH 列出 MediaStore 中的所有音乐

    android - Android L 与 Kitkat 中的 RAM 使用情况

    c# - 订购 ConcurrentDictionary。为什么这不起作用?

    c# - DataContractJsonSerializer 的静态实例 - 好的还是坏的设计?

    java - 在 doGet 中确定请求内容的类型

    java - 将键绑定(bind)到 JButton

    android - 从 Android 应用程序授权和访问 Google Tasks API?

    c# - 与 Entity Framework 和 MySQL 的乐观并发

    java - 解决向上转型/向下转型问题