JVM复用LocalVariableTable槽位有哪些可行代码示例?
生成复用局部变量槽位的Java字节码示例
要触发编译器生成istore_0后复用槽位执行astore_0的字节码,核心是让编译器识别到前一个局部变量的作用域已结束,从而复用其占用的槽位。以下是具体示例:
代码示例1:利用代码块隔离作用域
public class VarReuseDemo { public static void main(String[] args) { // 第一个作用域:int类型变量占用槽0 { int num = 123; System.out.println(num); } // 第二个作用域:Object类型变量复用槽0 { Object obj = new Object(); System.out.println(obj); } } }
编译后查看字节码
使用javap -c -l VarReuseDemo.class命令查看字节码及局部变量表,会得到类似如下输出:
public static void main(java.lang.String[]); Code: 0: sipush 123 3: istore_0 // 将int值存入槽0 4: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream; 7: iload_0 8: invokevirtual #3 // Method java/io/PrintStream.println:(I)V 11: new #4 // class java/lang/Object 14: dup 15: astore_0 // 将Object引用存入槽0(复用槽位) 16: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream; 19: aload_0 20: invokevirtual #5 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V 23: return LocalVariableTable: Start Length Slot Name Signature 4 7 0 num I 16 7 0 obj Ljava/lang/Object;
可以看到:
- 槽位0先被
int num占用,对应istore_0指令 - 当第一个代码块结束后,
num的作用域终止,槽位0被Object obj复用,对应astore_0指令
简化示例:无代码块的场景
如果前一个变量后续不再被使用,编译器也会自动复用槽位,无需代码块:
public class SimpleReuse { public static void test() { int x = 456; // x在此之后不再被引用 String msg = "hello world"; } }
编译后查看字节码,同样会出现istore_0存储int值,之后astore_0存储String引用的指令,LocalVariableTable也会显示槽0被两个变量复用。
关键逻辑
Java编译器会根据局部变量的作用域生命周期优化槽位使用:当一个变量的作用域结束(后续代码不再访问它),其占用的局部变量槽位就会被新的变量复用,不管新变量的类型是什么(只要槽位大小匹配,比如int和Object都占用1个槽位)。
内容的提问来源于stack exchange,提问作者Neo
相关产品推荐
相关产品推荐

