简介
java方法中定义的变量,它的生命周期是什么样的呢?是不是一定要等到方法结束,这个创建的对象才会被回收呢?
带着这个问题我们来看一下今天的这篇文章。
本地变量的生命周期
在类中,变量类型有类变量,成员变量和本地变量。
本地变量指的是定义在方法中的变量,如果我们在方法中定义了一个变量,那么这个变量的生命周期是怎么样的呢?
举个例子:
public void test(){ Object object = new Object(); doSomeThingElse(){ ... } }
在上面的test方法中,定义了一个object本地变量,然后又执行了一个方法。
因为在java中,我们无法直接控制对象的生命周期,对象的回收是由垃圾回收器自动进行的。
通常来说这个object对象会维持到整个test执行结束才会被回收。
现在我们考虑一个特殊的情况,如果doSomeThingElse这个方法是一个while循环,并且永远不会结束,那么这个创建出来的object对象会不会被回收呢?还是一直都存在内存中?
先说我们的结论,JVM非常智能,可以检测出来这种情况,将object对象进行回收。
举例说明
为了能够更好的说明问题,我们自定义一个Test对象,并在其创建和被回收之前打印相应的信息。
public static class Test { public Test() { System.out.println("创建对象 " + this); } public void test() { System.out.println("测试对象 " + this); } @Override protected void finalize() throws Throwable { System.out.println("回收对象 " + this); } }
然后做两个测试,第一个测试没有无限循环,第二个测试保持无限循环,循环通过一个volatile变量flag来控制:
public static void main(String[] args) throws InterruptedException { System.out.println("开始测试1"); resetFlag(); flag = tr<a style="color:transparent">本文来源gao($daima.com搞@代@#码(网5</a>ue; testLocalVariable(); System.out.println("等待Test1结束"); Thread.sleep(10000); System.out.println("开始测试2"); flag = true; testLocalVariable(); }
看一下testLocalVariable方法的定义:
public static void testLocalVariable() { Test test1 = new Test(); Test test2 = new Test(); while (flag) { // 啥都不做 } test1.test(); }
然后我们再启动一个线程做定时的GC。好了一切就绪,我们运行吧:
开始测试1
创建对象 com.flydean.LocalVariableReachability$Test@119d7047
创建对象 com.flydean.LocalVariableReachability$Test@776ec8df
回收对象 com.flydean.LocalVariableReachability$Test@776ec8df
测试对象 com.flydean.LocalVariableReachability$Test@119d7047
等待Test1结束
回收对象 com.flydean.LocalVariableReachability$Test@119d7047