【发布时间】:2014-06-17 20:57:14
【问题描述】:
我有以下方法被多个线程调用:
private final static Object lock = new Object();
public String createDirectory()
{
File file = new File("D:"+File.separator+"test");
if(!file.exists() || !file.isDirectory())//if file doesn't exist then create a new directory.
{
synchronized(lock)
{
if(!file.exists() || !file.isDirectory())//----> (1)
{
boolean isCreated = file.mkdir();
}
}
}
return file.getAbsolutePath();
}
JVM优化器是否有可能注释掉上面给定方法中标记为(1)的代码?我怀疑是因为,目录的存在会立即连续检查两次。将其视为不必要的冗余检查 JVM 优化器可能会注释掉该行 --> (1)。
【问题讨论】:
-
JVM 永远无法优化掉涉及方法调用的表达式,因为它不知道这些方法调用是否有副作用。
-
A JVM 只优化 BYTECODE 而不是 java 代码。它通过采用常见的 java 模式并将它们映射到更有效的字节码形式来进行优化。它永远不会“优化你的 java”cubrid.org/blog/dev-platform/understanding-jvm-internals
-
@DaoWen 不一定。如果已知函数没有任何副作用,则可以对其进行优化。一个简单的案例是
boolean doNothing() {return true;}。但在这种情况下,您的说法是正确的,因为File方法最终将作为操作系统调用而结束,并且 JVM 不能假设这些没有副作用(并且不受除他们的论点)。 -
@Mac 当然。首先,方法可以内联;方法中的代码被“复制粘贴”到调用站点,从而节省了调用方法的开销。此外,如果该方法没有任何副作用并且总是返回相同的值(或者可能返回不同的值,但从未使用过该值——老实说,我不确定优化能走多远),该方法可以完全删除。你可以在gist.github.com/yshavit/73d4bb96dcdaecd652d8 看到一个例子。如果 JVM 没有优化方法,那将花费 很长 时间。
-
@Mac 这不仅仅是冗余调用,如果每个冗余调用都可以被证明什么都不做的话。但基本上优化器的一般规则是,“如果你能告诉它在那里,除非看到方法运行得更快,那么它就坏了。”