Large memory chunk not garbage collected

Posted by Niels on Stack Overflow See other posts from Stack Overflow or by Niels
Published on 2013-06-19T08:56:32Z Indexed on 2013/06/24 16:22 UTC
Read the original article Hit count: 148

In a hunt for a memory-leak in my app I chased down a behaviour I can't understand. I allocate a large memory block, but it doesn't get garbage-collected resulting in a OOM, unless I explicit null the reference in onDestroy.

In this example I have two almost identical activities that switch between each others. Both have a single button. On pressing the button MainActivity starts OOMActivity and OOMActivity returns by calling finish(). After pressing the buttons a few times, Android throws a OOMException.

If i add the the onDestroy to OOMActivity and explicit null the reference to the memory chunk, I can see in the log that the memory is correctly freed.

Why doesn't the memory get freed automatically without the nulling?

MainActivity:

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

}

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

}

© Stack Overflow or respective owner

Related posts about android

Related posts about null