JVM JIT是否优化了几乎相同的新对象的创建?

时间:2013-02-05 19:20:19

标签: java jit functional-java

我正在阅读Functional Java库的源代码并注意到这一点:

public static <T> Option<T> none() {
    return new None<T>();
}

我想知道他们为什么不总是返回一个单例参数,特别是因为None的等式实现:

private static final class None<A> extends Option<A> { 

...

@Override
public int hashCode() {
    return 31;
}

@Override
public boolean equals(Object obj) {
   if (this == obj)
      return true;
   if (obj == null)
      return false;
   if (getClass() != obj.getClass())
      return false;
   return true;
}

}

所以我在Functional Java的论坛上搜索了一下,我找到了这个问题并回答:

  

是否可以设置它以便它不会为每次调用都创建一个新的None,我们可以在所有情况下使用单个对象来表示None吗?

     

不,但那么,谁在乎呢? JIT优化器现在可以很好地处理这些事情。

我的问题是JIT优化器如何以不必返回单例的方式处理它。我知道对象创建很便宜,但我认为单例会更便宜,在这种情况下它不会增加任何复杂性。

2 个答案:

答案 0 :(得分:3)

不,我知道的Java VM并没有进行这样的优化。使用现代JVM,创建新对象实际上更便宜,而不是寻找现有的JVM。他们在这个FAQ中的含义是,短暂的,丢弃的对象并不会真正影响垃圾收集时间(但可能会增加GC频率)。此外,我可以想象JVM执行转义分析并在堆栈上而不是在堆上分配这样的对象。

但是我认为这很浪费。查看java.lang.Integer(和所有其他原始包装器)缓存或Optional.absent() in Guava

public static <T> Optional<T> absent() {
  return (Optional<T>) Absent.INSTANCE;
}

在JDK中还有很多其他的优化:enum是单例,Collections.emptyList()总是返回相同的实例,等等。

答案 1 :(得分:1)

它更安全,否则我们需要依赖擦除。

创建对象可能比查找缓存对象更昂贵。请参阅java8&#39的可选:

http://hg.openjdk.java.net/lambda/lambda/jdk/file/ad394630273b/src/share/classes/java/util/Optional.java

   43     private final static Optional<?> EMPTY = new Optional<>();

   63      * There is no guarantee that it is a singleton.

   69     @SuppressWarnings("unchecked")
   70     public static<T> Optional<T> empty() {
   71         return (Optional<T>) EMPTY;
   72     }