【问题标题】:Does the Java compiler optimization a method called once by removing the method?Java编译器是否通过删除方法来优化一次调用的方法?
【发布时间】:2016-07-22 19:38:48
【问题描述】:

java 编译器(任何主流编译器)会采用类似的东西

void foo () {
    int x = 1;
    System.out.println(x);
}

void bar() {
    foo()
}

如果只在 bar 中调用 foo 方法并优化它,导致字节码也将由此生成:

void bar() {
    int x = 1;
    System.out.println(x);
}

【问题讨论】:

  • 很可能不会,因为 java 编译器并没有真正优化。他们把它留给 JVM
  • 最好不要。 foo 在定义它的类之外可见。也许如果 foo 是私有的。

标签: java javac compiler-optimization


【解决方案1】:

不,它没有。除了常量折叠之外,Javac 并没有做太多优化。在 java 中,优化是在运行时使用 JIT 进行的。

我创建了一个简短的示例来展示该方法如何没有被内联到字节码中,即使它只被调用了一次。私人和公共没有区别。

Compiled from "Test.java"
public class Test {
  public Test();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public static void main(java.lang.String[]);
    Code:
       0: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
       3: ldc           #3                  // String Hello before method
       5: invokevirtual #4                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
       8: invokestatic  #5                  // Method publicMethod:()V
      11: invokestatic  #6                  // Method privateMethod:()V
      14: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
      17: ldc           #7                  // String Hello after method
      19: invokevirtual #4                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
      22: return

  public static void publicMethod();
    Code:
       0: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
       3: ldc           #8                  // String The public method
       5: invokevirtual #4                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
       8: return

  private static void privateMethod();
    Code:
       0: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
       3: ldc           #9                  // String The private method
       5: invokevirtual #4                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
       8: return
}

【讨论】:

  • 这意味着如果它崩溃了,堆栈跟踪通常是优化版本,因为它是在运行时优化的?
猜你喜欢
  • 2011-03-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-08
  • 2015-04-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多