Java常量池在运行时删除

Java常量池在运行时删除,java,jvm,class-constants,jvm-bytecode,Java,Jvm,Class Constants,Jvm Bytecode,我有以下Java类: public class Test { public static void main(String[] args) { if (false) { log("String_to_be_never_printed_1"); } if (isPrintable()) { log("String_to_be_never_printed_2"); }

我有以下Java类:

public class Test {

    public static void main(String[] args) {
        if (false) {
            log("String_to_be_never_printed_1");
        }

        if (isPrintable()) {
            log("String_to_be_never_printed_2");
        }

    }

    private static boolean isPrintable() {
        return false;
    }

    private static void log(String s) {
        System.out.println(s);
    }

}
在这两个if语句中,结果都是false。当我输出该类的常量池表时,我得到:

Constant pool:
   #1 = Class              #2             // Test
   #2 = Utf8               Test
   ....
  #18 = Utf8               isPrintable
  #19 = Utf8               ()Z
  #20 = String             #21            // String_to_be_never_printed_2
  #21 = Utf8               String_to_be_never_printed_2
  #22 = Methodref          #1.#23         // Test.log:(Ljava/lang/String;)V
  #23 = NameAndType        #24:#25        // log:(Ljava/lang/String;)V
  ...
当看不到字符串“to”be“u never”printed“u 1”时,字符串“to”be“u never”printed“u 2”存在(#20)。这是预期的,因为编译器优化了第一个if语句


我的问题是VM是否会设法从常量池中删除字符串\u to\u be\u never\u printed\u 2(因为它永远不会被使用)

不会从常量池中删除任何内容。无论如何,这样做没有任何意义,因为删除不会对实际内存大小产生影响,堆内存中存在的对象可以通过JVM本身进行垃圾收集。常量池中的对象并不是垃圾收集的,因为它们对分配给JVM的内存大小没有太大影响。

javac没有编译时已知的内联常量。如果编译程序知道代码无法运行,则可以删除它+1您的意思是没有任何意义,因为字符串池的实际大小与堆大小相比根本不算什么?@benjamin.d不,我的意思是常量池是在内存中以固定大小设置的,在执行开始之前位于堆之外。垃圾收集只在堆中的内存上运行,在常量池上运行没有任何意义,因为没有任何其他内存可以进入此内存。回答这个问题可能会帮助您为什么不删除它