以下为本人测试得到的结果,从结果反推的结论。如果有不严谨的地方请指出。
会被回收。由于GC的可达性算法,置位空的内部类没有任何引用,会被标记为垃圾对象
测试:
先建立一个内部类,内部类有里面设置一个大的占内存的变量
public class Hello {
private InnnerClass innnerClass = null;
public void init(){
this.innnerClass = null;
}
public void create(){
innnerClass = new InnnerClass();
}
class InnnerClass{
HashMap<String, String> map = new HashMap<String, String>();
byte[] bs = new byte[1024 * 1024];
public void set(String a){
map.put("a",a);
}
public String get(String key){
return map.get(key);
}
}
}
调用:
public static void main(String[] args) {
while(true){
Hello hello = new Hello();
Hello hello2 = new Hello();
Hello hello3 = new Hello();
Hello hello4 = new Hello();
Hello hello5 = new Hello();
Hello hello6 = new Hello();
Hello hello7 = new Hello();
Hello hello8 = new Hello();
Hello hello9 = new Hello();
Hello hello10 = new Hello();
hello.create();
hello.init();
hello2.create();
hello2.init();
hello3.create();
hello3.init();
hello4.create();
hello4.init();
hello5.create();
hello5.init();
hello6.create();
hello6.init();
hello7.create();
hello7.init();
hello8.create();
hello8.init();
hello9.create();
hello9.init();
hello10.create();
}
}
虚拟机启动参数-Xms10m -Xmx10m -XX:MaxDirectMemorySize=5m -XX:+PrintGCDetails
这里需要注释掉init()
方法。
启动之后OOM
[GC (Allocation Failure) [PSYoungGen: 2048K->499K(2560K)] 2048K->987K(9728K), 0.0010512 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[GC (Allocation Failure) [PSYoungGen: 2216K->491K(2560K)] 8849K->7542K(9728K), 0.0009233 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Ergonomics) [PSYoungGen: 491K->433K(2560K)] [ParOldGen: 7051K->6970K(7168K)] 7542K->7404K(9728K), [Metaspace: 3535K->3535K(1056768K)], 0.0069182 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]
[Full GC (Ergonomics) [PSYoungGen: 1457K->1457K(2560K)] [ParOldGen: 6970K->6970K(7168K)] 8428K->8428K(9728K), [Metaspace: 3535K->3535K(1056768K)], 0.0026951 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Allocation Failure) [PSYoungGen: 1457K->1451K(2560K)] [ParOldGen: 6970K->6958K(7168K)] 8428K->8410K(9728K), [Metaspace: 3535K->3535K(1056768K)], 0.0046333 secs] [Times: user=0.08 sys=0.00, real=0.01 secs]
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at com.java.task.Hello$InnnerClass.<init>(Hello.java:40)
at com.java.task.Hello.create(Hello.java:24)
at com.java.task.HelloWorld.main(HelloWorld.java:29)
然后我们放开init方法,这个方法会把内部类的引用置位null。如果这时候对象和内部类保持联系,则不会被清理,会继续出现OOM异常;如果被清理了则不会吧报OOM异常
[Full GC (Ergonomics) [PSYoungGen: 1064K->0K(2560K)] [ParOldGen: 6490K->1370K(7168K)] 7555K->1370K(9728K), [Metaspace: 4045K->4045K(1056768K)], 0.0032143 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[GC (Allocation Failure) --[PSYoungGen: 1064K->1064K(2560K)] 7555K->7555K(9728K), 0.0002192 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
最终没有报异常,也就是说为空的内部类会被垃圾回收器回收。