在寻找我的应用程序中的内存泄漏时,我追查了一个我无法理解的行为。我分配了一个大的内存块,但它不会被垃圾收集,从而导致 OOM,除非我在 onDestroy 中显式地将引用设为空。
在这个例子中,我有两个几乎相同的活动,它们在彼此之间切换。两者都有一个按钮。在按下按钮 MainActivity 启动 OOMActivity 并且 OOMActivity 通过调用 finish() 返回。按下按钮几次后,Android 会抛出 OOMException。
如果我将 onDestroy 添加到 OOMActivity 并显式 null 对内存块的引用,我可以在日志中看到内存已正确释放。
为什么在没有清零的情况下内存不会自动释放?
主要活动:
package com.example.oom;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class MainActivity extends Activity implements OnClickListener {
private int buttonId;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
System.gc();
Button OOMButton = new Button(this);
OOMButton.setText("OOM");
buttonId = OOMButton.getId();
setContentView(OOMButton);
OOMButton.setOnClickListener(this);
}
@Override
public void onClick(View v) {
if (v.getId() == buttonId) {
Intent leakIntent = new Intent(this, OOMActivity.class);
startActivity(leakIntent);
}
}
}
OOM活动:
public class OOMActivity extends Activity implements OnClickListener {
private static final int WASTE_SIZE = 20000000;
private byte[] waste;
private int buttonId;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Button BackButton = new Button(this);
BackButton.setText("Back");
buttonId = BackButton.getId();
setContentView(BackButton);
BackButton.setOnClickListener(this);
waste = new byte[WASTE_SIZE];
}
public void onClick(View view) {
if (view.getId() == buttonId) {
finish();
}
}
}