I have code like this:
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();
}
}
I run it with jvm option -verbose:gc
, My java env:
java version "1.7.0_79"
Java(TM) SE Runtime Environment (build 1.7.0_79-b15)
Java HotSpot(TM) 64-Bit Server VM (build 24.79-b02, mixed mode)
CASE-1:
Run with method test1()
invoked, console output:
[GC 13312K->616K(116736K), 0.0014246 secs]
[Full GC 616K->554K(116736K), 0.0125266 secs]
data
var is collected by JVM.
CASE-2:
Run with method test2()
invoked, console output:
[GC 13312K->10936K(116736K), 0.0092033 secs]
[Full GC 10936K->10788K(116736K), 0.0155626 secs]
data
var is not collected.
I generate bytecode for methods by command 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
My guess is: When method test1()
execute to stack map frame, the local variables is reset and lead to slot_1(data
located) is cleared.
Someone can give a detail explain?