Java JVM是否优化了不必要的自动装箱?

Java JVM是否优化了不必要的自动装箱?,java,optimization,jvm,boxing,autoboxing,Java,Optimization,Jvm,Boxing,Autoboxing,javac或JIT是否优化了不必要的自动装箱?假设我们有一个关于这段代码的例子 for(int i=0; i<100000; i++) { f(i); } void f(Integer i) { System.out.println(i); } for(int i=0;iJVM可以自由地进行它喜欢的任何优化,因此一些JVM可能会对此进行优化 但是,假设它会这样做是一种不好的做法,对于每一个这样做的JVM,可能有几个不这样做 查看以下内容时,只需更改方法,使其接受与其内部

javac或JIT是否优化了不必要的自动装箱?假设我们有一个关于这段代码的例子

for(int i=0; i<100000; i++) {
    f(i);
}

void f(Integer i) {
    System.out.println(i);
}

for(int i=0;iJVM可以自由地进行它喜欢的任何优化,因此一些JVM可能会对此进行优化

但是,假设它会这样做是一种不好的做法,对于每一个这样做的JVM,可能有几个不这样做


查看以下内容时,只需更改方法,使其接受与其内部使用的相同装箱级别的类型。

public class a
{
    public static void main(String[] args)
    {
        for (int i = 0; i < 100000; i++)
            f(i);
    }

    public static void f(Integer i)
    {
        System.out.println(i);
    }
}

这个字节码告诉我们正在调用
Integer.valueOf()
main 9:
)但是,正如@Tim B所指出的,JVM内部发生的事情是另一件无法预测的事情。最好假设最坏的情况是JVM不会对其进行优化。

OpenJDK和HotSpot JVM 5-8不会对它们进行优化,除非它们是未使用(即使如此也不总是)

但是,当您询问或回答这些问题时,有一种透视感是很重要的。与将数字转换为字符串的代码(JVM的操作方式)相比,自动生成是微不足道的,而与写入控制台相比,这是微不足道的这将节省99.99%以上的时间,因此在这里担心自动装箱就是担心错误的事情


在您的特定情况下,它无法优化自动装箱的方式,因为调用了PrintStream.println(Object)。JVM通常不了解库的功能,也不能假设调用PrintStream.println(int)我会做同样的事情。

好吧,这是我在一次技术采访中遇到的问题,问这个问题的人希望得到具体的答案。我们谈论的是HotSpot JVM。我理解你的观点,并同意你的观点。
javac
几乎没有优化功能,读取字节码并不能很好地测试优化时代码会这样做。那么内存效率呢?如果在每次调用中发生自动装箱,将有大约99873(100000-127)个不必要的整数实例被创建。我不同意我不应该担心自动装箱。但是我现在明白了为什么这种情况不会被优化,因为调用了println(Object)@Sebastian correct,我不是说它什么都不做,只是转换成文本的成本要高得多,而写入屏幕的成本要高得多。试着计时取println make与取整数make的差异。你不需要测量它,差异如此之大,你会看到差别。
Compiled from "a.java"
public class a {
  public a();
    Code:
       0: aload_0       
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return        

  public static void main(java.lang.String[]);
    Code:
       0: iconst_0      
       1: istore_1      
       2: iload_1       
       3: ldc           #2                  // int 100000
       5: if_icmpge     21
       8: iload_1       
       9: invokestatic  #3                  // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      12: invokestatic  #4                  // Method f:(Ljava/lang/Integer;)V
      15: iinc          1, 1
      18: goto          2
      21: return        

  public static void f(java.lang.Integer);
    Code:
       0: getstatic     #5                  // Field java/lang/System.out:Ljava/io/PrintStream;
       3: aload_0       
       4: invokevirtual #6                  // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
       7: return        
}