测试用例
ObjA
public class ObjA { private int idx; public ObjA(int i){ idx = i; System.out.println("创建对象:ObjA("+i+")"); } protected void finalize() throws Throwable{ super.finalize(); System.out.println("回收对象:ObjA("+idx+")"); } public ObjB getObjB(int i){ ObjB b = new ObjB(i); return b; } }
ObjB
public class ObjB { private int idx; public ObjB(int i) { idx = i; System.out.println("创建对象:ObjB("+i+")"); } protected void finalize() throws Throwable{ super.finalize(); System.out.println("回收对象:ObjB("+idx+")"); } public String getStr(){ System.out.println("调用 ObjB"+idx+".getStr();"); return "getStr()"; } }
测试
测试1
代码
public class Main { public static void main(String[] args) { for (int i = 0; i < 10; i++) { ObjA obja = new ObjA(i); obja.getObjB(i).getStr(); obja = null; } System.gc(); } }
运行结果
创建对象:ObjA(0)
创建对象:ObjB(0)
调用 ObjB0.getStr();
创建对象:ObjA(1)
创建对象:ObjB(1)
调用 ObjB1.getStr();
创建对象:ObjA(2)
创建对象:ObjB(2)
调用 ObjB2.getStr();
创建对象:ObjA(3)
创建对象:ObjB(3)
调用 ObjB3.getStr();
创建对象:ObjA(4)
创建对象:ObjB(4)
调用 ObjB4.getStr();
创建对象:ObjA(5)
创建对象:ObjB(5)
调用 ObjB5.getStr();
创建对象:ObjA(6)
创建对象:ObjB(6)
调用 ObjB6.getStr();
创建对象:ObjA(7)
创建对象:ObjB(7)
调用 ObjB7.getStr();
创建对象:ObjA(8)
创建对象:ObjB(8)
调用 ObjB8.getStr();
创建对象:ObjA(9)
创建对象:ObjB(9)
调用 ObjB9.getStr();
回收对象:ObjB(9)
回收对象:ObjA(9)
回收对象:ObjB(8)
回收对象:ObjA(8)
测试2
代码
public class Main { public static void main(String[] args) { for (int i = 0; i < 10; i++) { ObjA obja = new ObjA(i); obja.getObjB(i).getStr(); obja = null; if (i % 2 ==0){ System.gc(); } } } }
运行结果
创建对象:ObjA(0)
创建对象:ObjB(0)
调用 ObjB0.getStr();
创建对象:ObjA(1)
创建对象:ObjB(1)
调用 ObjB1.getStr();
创建对象:ObjA(2)
创建对象:ObjB(2)
调用 ObjB2.getStr();
回收对象:ObjB(0)
回收对象:ObjB(2)
回收对象:ObjA(2)
回收对象:ObjB(1)
回收对象:ObjA(1)
回收对象:ObjA(0)
创建对象:ObjA(3)
创建对象:ObjB(3)
调用 ObjB3.getStr();
创建对象:ObjA(4)
创建对象:ObjB(4)
调用 ObjB4.getStr();
创建对象:ObjA(5)
创建对象:ObjB(5)
调用 ObjB5.getStr();
创建对象:ObjA(6)
创建对象:ObjB(6)
调用 ObjB6.getStr();
回收对象:ObjB(4)
回收对象:ObjB(6)
回收对象:ObjA(6)
回收对象:ObjB(5)
回收对象:ObjA(5)
回收对象:ObjA(4)
回收对象:ObjB(3)
回收对象:ObjA(3)
创建对象:ObjA(7)
创建对象:ObjB(7)
调用 ObjB7.getStr();
创建对象:ObjA(8)
创建对象:ObjB(8)
调用 ObjB8.getStr();
创建对象:ObjA(9)
创建对象:ObjB(9)
调用 ObjB9.getStr();
回收对象:ObjB(8)
回收对象:ObjA(8)
回收对象:ObjB(7)
回收对象:ObjA(7)
总结分析
从以上测试分析得知,在循环语句中,如果有大量对象创建,需要显示地执行System.gc();方法。 否则等JVM自己去处理垃圾的时候,可能已经造成OutOfMemory错误了。
GC也不能执行得太频繁,所以建议,根据对象的内存占用情况决定循环多少次,显示地调用一次GC方法。