我一直在研究内存泄漏,并使用内存分析工具进行检查。因此,作为一个练习,我有以下泄漏活动的代码,因为匿名内部类保存了对活动的引用。以下是代码:
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个旋转。](https://istack.dev59.com/QNPqh.webp)
![输入图像描述](https://istack.dev59.com/KCuak.webp)
现在,请考虑以下代码:
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可以自由地回收Activity对象,而不会受到线程类的限制。
以下是同一事物的MAT截图:
我对第二组截图有些困惑,其中有5个finalizer引用。我通过Google了解到,JVM在对象即将被GC时将其添加到引用队列中。我期望尽管会发生这种情况,但这些更改在MAT中不会可用,因为我认为GC不需要花费太多时间来释放那些引用。即使我使用13次旋转,结果也相同,有12个finalizer引用。我可能错了,但我认为MAT只会显示1个Activity对象,因为其他对象必须已经被GC了。任何关于终结器引用队列以及垃圾收集过程的帮助都将不胜感激。谢谢。