JVM/Compiler优化对象的未使用属性

rev*_*zum 3 java optimization jvm

我的类包含一些从未在任何地方使用的属性(这是我真实场景的演示).我听说JVM优化了我们的Java代码.

JVM/Compiler是否优化/删除对象的未使用属性?

public class A {
   private int unused1 = 100;// never called anywhere inside object
   public int unused2 = 999;// never called anywhere in the application 
}
Run Code Online (Sandbox Code Playgroud)

我知道我需要努力学习JVM,编译器和优化.但答案是必要的,因为在短时间内我必须决定是否将从大型代码库(大约10,000个java文件)中手动删除所有(尽可能多的)未使用的变量,或者仅依赖于JVM优化.

期待一些有趣和富有成效的建议.

Huw*_*nes 5

TL; DR:不,JVM编译器(javac)不会优化未使用的变量.

我们来看看javac编译器生成的字节码.

使用它作为测试类:

public class Test {

    private int test = 5;
    private int test2 = 10;
    private String aString = "HelloWorld";
}
Run Code Online (Sandbox Code Playgroud)

生产:

Classfile /C:/Users/Huw/Desktop/Test.class


Last modified 19-Apr-2016; size 331 bytes
  MD5 checksum 1c49b13d1d5d8a2c52924b20753122af
  Compiled from "Test.java"
public class Test
  minor version: 0
  major version: 52
  flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
   #1 = Methodref          #7.#19         // java/lang/Object."<init>":()V
   #2 = Fieldref           #6.#20         // Test.test:I
   #3 = Fieldref           #6.#21         // Test.test2:I
   #4 = String             #22            // HelloWorld
   #5 = Fieldref           #6.#23         // Test.aString:Ljava/lang/String;
   #6 = Class              #24            // Test
   #7 = Class              #25            // java/lang/Object
   #8 = Utf8               test
   #9 = Utf8               I
  #10 = Utf8               test2
  #11 = Utf8               aString
  #12 = Utf8               Ljava/lang/String;
  #13 = Utf8               <init>
  #14 = Utf8               ()V
  #15 = Utf8               Code
  #16 = Utf8               LineNumberTable
  #17 = Utf8               SourceFile
  #18 = Utf8               Test.java
  #19 = NameAndType        #13:#14        // "<init>":()V
  #20 = NameAndType        #8:#9          // test:I
  #21 = NameAndType        #10:#9         // test2:I
  #22 = Utf8               HelloWorld
  #23 = NameAndType        #11:#12        // aString:Ljava/lang/String;
  #24 = Utf8               Test
  #25 = Utf8               java/lang/Object
{
  public Test();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=2, locals=1, args_size=1
         0: aload_0
         1: invokespecial #1                  // Method java/lang/Object."<init>":()V
         4: aload_0
         5: iconst_5
         6: putfield      #2                  // Field test:I
         9: aload_0
        10: bipush        10
        12: putfield      #3                  // Field test2:I
        15: aload_0
        16: ldc           #4                  // String HelloWorld
        18: putfield      #5                  // Field aString:Ljava/lang/String;
        21: return
      LineNumberTable:
        line 1: 0
        line 3: 4
        line 4: 9
        line 5: 15
}
SourceFile: "Test.java"
Run Code Online (Sandbox Code Playgroud)

如您所见,编译器仍然分配字段属性.

所以不,未使用的变量仍将被分配指针(对象)和内存(对于基元).