package com.jvm.test; public class LocalvarGC { class gctest{ byte [] b = null; public gctest(){ System.out.println("我被创建了,我的代号是:"+this.hashCode()); b = new byte[1024*1024*2]; } @Override protected void finalize() throws Throwable { System.out.println("我被回收了,我的代号是:"+this.hashCode()); super.finalize(); } } public void test1(){ gctest g = new gctest(); //byte [] b = new byte[6*1204*1024]; System.gc(); } public void test2(){ gctest g = new gctest(); g = null; System.gc(); } public void test3(){ { gctest g = new gctest(); } System.gc(); } public void test4(){ { gctest g = new gctest(); } gctest b = new gctest(); System.gc(); } public void test5(){ test1(); System.gc(); } public static void main(String[] args) throws InterruptedException { System.out.println("max:"+Runtime.getRuntime().maxMemory()/1024 + " k"); System.out.println("free:"+Runtime.getRuntime().freeMemory()/1024 + " k"); System.out.println("total:"+Runtime.getRuntime().totalMemory()/1024 + " k"); System.out.println("---------"); LocalvarGC t = new LocalvarGC(); t.test1(); // t.test2(); // t.test3(); // t.test4(); // t.test5(); Thread.sleep(2000); System.out.println("---------"); System.out.println("max:"+Runtime.getRuntime().maxMemory()/1024 + " k"); System.out.println("free:"+Runtime.getRuntime().freeMemory()/1024 + " k"); System.out.println("total:"+Runtime.getRuntime().totalMemory()/1024 + " k"); } }
1.运行test1结果如下:
max:1824256 k
free:121937 k
total:123904 k
---------
我被创建了,我的代号是:366712642
[GC (System.gc()) 4014K->2704K(123904K), 0.0011886 secs]
[Full GC (System.gc()) 2704K->2582K(123904K), 0.0054202 secs]
---------
max:1824256 k
free:120665 k
total:123904 k
分析:可见,并没有打印出被回收的信息,因为局部变量g对gctest实例是强引用关系,系统是无法对gctest实例进行回收的。
2.运行test2结果如下:
max:1824256 k
free:121937 k
total:123904 k
---------
我被创建了,我的代号是:366712642
[GC (System.gc()) 4014K->2688K(123904K), 0.0018442 secs]
[Full GC (System.gc()) 2688K->2582K(123904K), 0.0059582 secs]
我被回收了,我的代号是:366712642
---------
max:1824256 k
free:120010 k
total:123904 k
分析:实例失去了强引用,也就是没人再使用它了,那么也就是垃圾了,系统于是把它回收了
3.运行test3结果如下:
free:121937 k
total:123904 k
---------
我被创建了,我的代号是:366712642
[GC (System.gc()) 4014K->2720K(123904K), 0.0014949 secs]
[Full GC (System.gc()) 2720K->2582K(123904K), 0.0059850 secs]
---------
max:1824256 k
free:120665 k
total:123904 k
分析:尽管局部变量g已经失效,但g依然在局部变量表中,此方法还未结束,所有对实例的引用还是有效的,所有实例没有被回收
4.运行test4结果如下:
max:1824256 k
free:121937 k
total:123904 k
---------
我被创建了,我的代号是:366712642
我被创建了,我的代号是:1829164700
[GC (System.gc()) 6062K->4752K(123904K), 0.0024048 secs]
[Full GC (System.gc()) 4752K->4630K(123904K), 0.0063782 secs]
我被回收了,我的代号是:366712642
---------
max:1824256 k
free:117962 k
total:123904 k
分析:发现实例(366712642)被回收了,是因为在test3中我们知道局部变量尽管失效了,但依然存在,对实例的引用还在。当再创建一个局部变量时,新的局部变量会复用原先的失效的局部变量的位置,于是原先的局部变量就被销毁了,于是引用解除,顺利回收。
5.运行test5结果如下:
max:1824256 k
free:121937 k
total:123904 k
---------
我被创建了,我的代号是:366712642
[GC (System.gc()) 4014K->2688K(123904K), 0.0016433 secs]
[Full GC (System.gc()) 2688K->2582K(123904K), 0.0055240 secs]
[GC (System.gc()) 2582K->2582K(123904K), 0.0003024 secs]
[Full GC (System.gc()) 2582K->2582K(123904K), 0.0026905 secs]
我被回收了,我的代号是:366712642
---------
max:1824256 k
free:120010 k
total:123904 k
分析:我们知道,test1是无法回收实例的,因为有引用存在,在test5中,先调用test1,当test1返回后,那么test1所对应的栈帧就被销毁了,于是局部变量和引用也不存在了,所有但test5再次gc时,实例被顺利回收。