我一直在研究内存泄漏,并使用内存分析器工具来检查它们。因此,作为实践,我有以下代码,它泄漏了一个活动,因为匿名内部类持有对该活动的引用。代码如下:
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个终结器引用。我用谷歌搜索了一下,发现一旦对象将要被GCed,JVM就会将它们添加到引用队列中。我预计,虽然这会发生,但这些更改不会在MAT中可用,因为我认为GC不会花费太多时间来释放这些引用。即使我使用了13次旋转,结果也是一样的,只有12次终结器引用。我可能错了,但我认为MAT只会显示1个Activity对象,因为其他对象一定是GCed。任何关于终结引用队列的帮助,以及在垃圾收集过程中进行的进程,都将不胜感激。谢谢。
发布于 2015-04-25 14:29:59

选择Finalizer概述。它提供了等待终结器运行的对象数量的信息,以及终结器线程的其他相关信息。
https://stackoverflow.com/questions/29654896
复制相似问题