大内存块不是垃圾收集

Nie*_*els 16 null android garbage-collection out-of-memory

在我的应用程序寻找内存泄漏时,我追查了一个我无法理解的行为.我分配了一个大的内存块,但它没有得到垃圾收集导致OOM,除非我在onDestroy中显式null引用.

在这个例子中,我有两个几乎相同的活动,可以在彼此之间切换.两者都有一个按钮.按下按钮MainActivity通过调用finish()启动OOMActivity和OOMActivity返回.按几次按钮后,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);
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

OOMActivity:

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();
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

Luc*_*yMe 1

Activity 销毁并不意味着类销毁,仅仅因为您看不到该类并不意味着操作系统(在本例中为 Android)丢失了对它的所有引用并结束它。这就是为什么即使在他们指定清除任何句柄和对象的文档中,您也不再需要防止内存泄漏。干杯。