【问题标题】:Does escape analysis handles Thread.holdsLock() properly?逃逸分析是否正确处理 Thread.holdsLock()?
【发布时间】:2017-12-06 00:06:57
【问题描述】:

当我使用-XX:+DoEscapeAnalysis -server 运行此示例时,它运行良好(打印结果为真):

final Object lock = new Object();
synchronized (lock) {
    System.out.println(Thread.holdsLock(lock)); // prints true
}

另一方面,简短且不太详细的 Java HotSpot™ Virtual Machine Performance Enhancements 文档说明如下:

服务器编译器还消除了所有非全局转义对象的锁。

所以,如果逃逸分析消除了这里不必要的同步,它应该打印false

我猜逃逸分析可以正确处理holdsLock(消除锁不会破坏holdsLock()),但我希望看到一些官方参考或相关的JVM源代码sn-ps。

【问题讨论】:

  • 此代码应该永远打印false。只有在不改变代码语义的情况下才允许进行优化。如果 JVM 决定消除锁,此时它还负责将 Thread.holdsLock(lock) 替换为常量 true。没有必要引用源代码来支持不允许优化更改语义的基本属性。除此之外,还有不止一个实现,所以引用其中一个的源代码无论如何都不能作为证明。当您调用 Thread.holdsLock(lock)... 时,JVM 也可能决定不进行优化...

标签: java jvm escape-analysis


【解决方案1】:

Thread.holdsLock是JDK中的native方法,不是JVM intrinsic

这意味着,Thread.holdsLock 的实现是 JIT 编译器的黑匣子。由于此方法接受lock 作为参数,因此lock 不能再被视为本地不可转义对象。 JVM 肯定知道,lock 会转义,所以在这个例子中分配和同步都不会被消除。

但是,正如@Holger 所注意到的,即使holdsLock 是JVM 内在函数,它也不应该返回false,否则这将违反规范。任何 JVM 优化都不会破坏程序的正确性。

【讨论】:

  • 一般情况下,99.9% 的库调用对 JVM 没有特殊的优化或理解。有一个非常简短的非常具体的案例列表,根据 JVM 设计人员认为它非常常见的情况和避免复杂性的快速胜利,会发生这种情况。 +1
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-01-03
  • 2015-06-10
  • 2019-01-12
  • 1970-01-01
  • 2019-07-04
  • 2022-01-10
  • 1970-01-01
相关资源
最近更新 更多