【发布时间】:2018-02-24 06:30:23
【问题描述】:
我有这样的代码:
public class TestGC {
private static final int _10MB = 10 * 1024 * 1024; // 10MB
public static void main(String[] args) {
test1();
// test2();
}
public static void test1() {
int i = 1;
if (i > 0) {
byte[] data = new byte[_10MB];
}
System.gc();
}
public static void test2() {
if (true) {
byte[] data = new byte[_10MB];
}
System.gc();
}
}
我使用 jvm 选项 -verbose:gc 运行它,我的 java env:
java版本“1.7.0_79”
Java(TM) SE 运行时环境(内部版本 1.7.0_79-b15)
Java HotSpot(TM) 64 位服务器 VM(内部版本 24.79-b02,混合模式)
案例一:
调用方法test1()运行,控制台输出:
[GC 13312K->616K(116736K), 0.0014246 secs]
[Full GC 616K->554K(116736K), 0.0125266 secs]
data var 被 JVM 收集。
案例二:
调用方法test2()运行,控制台输出:
[GC 13312K->10936K(116736K), 0.0092033 secs]
[Full GC 10936K->10788K(116736K), 0.0155626 secs]
data var 未被收集。
我通过命令javap为方法生成字节码:
test1()
public static void test1();
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=1, locals=2, args_size=0
0: iconst_1
1: istore_0
2: iload_0
3: ifle 11
6: ldc #3 // int 10485760
8: newarray byte
10: astore_1
11: invokestatic #4 // Method java/lang/System.gc:()V
14: return
LineNumberTable:
line 11: 0
line 12: 2
line 13: 6
line 15: 11
line 16: 14
LocalVariableTable:
Start Length Slot Name Signature
11 0 1 data [B
2 13 0 i I
StackMapTable: number_of_entries = 1
frame_type = 252 /* append */
offset_delta = 11
locals = [ int ]
test2()
public static void test2();
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=1, locals=1, args_size=0
0: ldc #3 // int 10485760
2: newarray byte
4: astore_0
5: invokestatic #4 // Method java/lang/System.gc:()V
8: return
LineNumberTable:
line 20: 0
line 22: 5
line 23: 8
LocalVariableTable:
Start Length Slot Name Signature
5 0 0 data [B
我的猜测是:当方法test1()执行堆栈映射帧时,局部变量被重置并导致slot_1(data位于)被清除。
有人可以详细解释一下吗?
【问题讨论】: