Java 在运行时移除常量池
Java constant pool removal at runtime
我有以下 Java class:
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 语句中,结果都将为假。当我为这个 class 输出常量池 table 时,我得到:
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
...
String_to_be_never_printed_2 存在 (#20),而 String_to_be_never_printed_1 无处可见。这是预期的,因为编译器优化了第一个 if 语句。
我的问题是 VM 是否会设法从常量池中删除 String_to_be_never_printed_2(因为它永远不会被使用)?
不会从常量池中删除任何内容。无论如何,这没有任何意义,因为删除对实际内存大小没有影响
存在于堆内存中的对象有资格由 JVM 本身进行垃圾回收。常量池中的对象不会全部被垃圾回收,因为它们对分配给 JVM 的内存大小没有太大影响。
我有以下 Java class:
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 语句中,结果都将为假。当我为这个 class 输出常量池 table 时,我得到:
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
...
String_to_be_never_printed_2 存在 (#20),而 String_to_be_never_printed_1 无处可见。这是预期的,因为编译器优化了第一个 if 语句。
我的问题是 VM 是否会设法从常量池中删除 String_to_be_never_printed_2(因为它永远不会被使用)?
不会从常量池中删除任何内容。无论如何,这没有任何意义,因为删除对实际内存大小没有影响
存在于堆内存中的对象有资格由 JVM 本身进行垃圾回收。常量池中的对象不会全部被垃圾回收,因为它们对分配给 JVM 的内存大小没有太大影响。