7
我一直在研究内存泄漏并使用内存分析工具来检查它们。所以,作为一种实践,我有下面的代码泄露一项活动,因为匿名内部类拥有对活动的引用。下面的代码:内存泄漏终结者错误
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
exampleOne();
}
private void exampleOne() {
new Thread() {
@Override
public void run() {
while (true) {
SystemClock.sleep(1000);
}
}
}.start();
}
}
我对这里上述泄漏存储器分析器图像(6转):
这是相当清楚的是有6级保持于外的隐式引用运行的线程活动,从而防止垃圾被垃圾收集。
现在,请考虑下面的代码:
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
exampleTwo();
}
private void exampleTwo() {
new MyThread().start();
}
private static class MyThread extends Thread {
@Override
public void run() {
while (true) {
SystemClock.sleep(1000);
}
}
}
}
在这里,我所做的类的静态,从而使有到外的活动没有参考和GC可以自由回收活动对象,而不由线程被阻止类。
下面是相同的MAT截图:
我有关于第二组截图,其中有5所终结引用的混乱。我搜索了一下,发现JVM在对象被加入GC之后会将这些对象添加到引用队列中。我预计,虽然会发生这种情况,但MAT中不会提供这些更改,因为我认为GC不会花费太多时间来释放这些引用。即使我使用13次旋转,结果也是一样的,有12次终结器参考。我可能是错的,但我认为MAT只会显示1个Activity对象,因为其他人必须已经被GCed。任何关于最终化引用队列的帮助,以及在垃圾回收时继续进行的过程,我们将不胜感激。谢谢。
你试过强制垃圾收集吗? –
好吧,不,我没有尝试过强迫。对于第二种情况,我认为GC会自动回收内存,因为没有任何阻止它的做法。将对象放入终结器队列中表明确实已经准备好回收内存了,但是我的困惑是为什么它没有在MAT中反映出来。 –