步骤:
1、activity中,有一个成员变量,这个成员变量是一个自定义类TestInnerClass
2、这个自定义TestInnerClass,里面有个内部类InnerClass,是个Runnable接口。
3、运行这个activity,然后调用了testInnerClass.run(),线程就会在后台一直跑。然后关闭activity。
代码如下:
public class TestActivity extends Activity {
private TestInnerClass testInnerClass;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
testInnerClass = new TestInnerClass();
testInnerClass.run();
}
}
public class TestInnerClass {
public void run(){
InnerClass innerClass = new InnerClass();
Thread thread = new Thread(innerClass);
thread.start();
}
public class InnerClass implements Runnable{
private Context context;
public InnerClass() {
}
public InnerClass(Context context) {
this.context = context;
}
@Override
public void run() {
while (true) {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
在此过程中,我猜测:
1、InnerClass是个内部类,在TestInnerClass的run()方法中,new了这个对象,那么TestInnerClass就会被InnerClass持有,而InnerClass这个runnable接口,又会被thread持有,因此,TestInnerClass在activity关闭之后,不会被释放。
2、由于TestInnerClass没有被释放,这时候就触及到了我的知识盲区,这个时候activity到底能不能被释放呢?gc规则的话,能否回收这个对象,要看可达性,activity是没有被其他地方强引用的,但是它的成员变量TestInnerClass又被thread持有,那activity会怎样呢?
然后我用android studio看了一下关闭activity后的内存:
然后,对于TestInnerClass,确实存在于内存:
我的疑问是:
activity被回收的时候,成员变量在跟activity不同生命周期的thread中被引用。那么java的回收有没有可能存在是,实例被回收了,但是实例中的成员变量还在内存中?
https://blog.csdn.net/u013534071/article/details/80254127
首先先回答你的问题:
问题:由于TestInnerClass没有被释放,这时候就触及到了我的知识盲区,这个时候activity到底能不能被释放呢?
回答:activity对象没有被释放
问题:实例被回收了,但是实例中的成员变量还在内存中?
答案:成员变量不会还在内存中。
如果证明?
可以在
Thread.sleep(2000);
这一行打断点,然后观察内存即可。
TestInnerClass 是Activity的内部类,自动的它是持有外部Activity的实例对象的
所以,Activity实例不会被释放,同样的它内部的成员变量也不会被释放,
你这样写是会造成Activity这个对象的内存泄漏的
经过一段时间的探索以后,发现我这个写法testInnerClass = new TestInnerClass(); InnerClass innerClass = new InnerClass();都不是内部类的写法,只是生成了一个对象。因此不会持有外部类这个说法。因此activity能回收。而新起的线程有它自己的生命周期,因此profile能看到。