6

I've recently learned how much memory can be wasted by leaking context and how to test for such leaks with a memory dump after a screen orientation change. The new activity should be instantiated and created, the original destroyed and collected. However, unless I'm leaking memory and don't see it, the activity below doesn't seem to be collected if it starts a different activity and destroys itself:

public class Foo extends Activity {
    private Button button;

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        button = new Button(this);
        button.setOnClickListener(new OnClickListener() {
            public void onClick(View view) {
                startActivity(new Intent(Foo.this, Bar.class));
                finish();
            }
        });

        setContentView(button);
    }

    protected void onDestroy() {
        super.onDestroy();

        button.setOnClickListener(null);

        Log.e("you're it", "isFinishing() == " + isFinishing());
    }
}

 

public class Bar extends Activity {
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        TextView textView = new TextView(this);
        textView.setText("hello, world");

        setContentView(textView);
    }
}

Here's the memory dump info, taken after clicking the button to start Bar and requesting garbage collection a few times:

Class Name                                               | Shallow Heap | Retained Heap
----------------------------------------------------------------------------------------
com.test.testProject.Foo @ 0x4135b188                    |          184 |         2,208
 mOuterContext android.app.ContextImpl @ 0x4135b390      |           96 |           392
  <Java Local> java.lang.Thread @ 0x40996460  main Thread|           80 |         1,416
  mContext android.media.AudioManager @ 0x4135b480       |           48 |           176
----------------------------------------------------------------------------------------

Based on this, I thought that throwing an extra finish between activities would make the first one eligible for collection and allow me to test for leaks an additional way, is this sensible? Am I leaking memory? Is there some reason Android would want to keep this destroyed activity around?

Community
  • 1
  • 1
lwiseman
  • 750
  • 7
  • 29
  • 1
    You aren't leaking memory. I believe that the GC has simply not yet decided to clean up the activity - even though you have requested garbage collection. What version of android are you testing it on? I think if you try the same thing on 3.0+, the GC will remove it more quickly – Wozza Dec 09 '11 at 02:03
  • Perhaps check for an `Intent` object still active when analyzing the dump file. It will probably point to Foo and Bar. – Wozza Dec 09 '11 at 02:13
  • This is on the 4.0 platform. Also, there are two Intent instances, one being referenced by Foo and one being referenced by Bar. That makes sense, I think, because each Activity has a reference to it's Intent for getIntent(). It's not the Intent keeping the Activity alive, is it? – lwiseman Dec 09 '11 at 09:05
  • 1
    In the development options you can set a flag called "Do not keep activities" see if this helps at all, if it doesn't then i will have a deeper look as nothing screams to me leak. It might be it just hasn't gcd it yet – Paul Harris Nov 02 '12 at 13:59
  • call 'finish()' will cause onDestory() callback. That means ur activity is done and should be closed... – Sim Sun Apr 08 '13 at 03:43
  • What Wozza said was helpful to me. Even after explicitly invoking GC from DDMS, the activity was not destroyed. Only after a minute or two and some more GC invocations did the trailing Context reference disappear allowing garbage collection. – Guykun Sep 13 '13 at 13:40

1 Answers1

0

maybe u can try the code as below :

 button.setOnClickListener(new OnClickListener() {
        public void onClick(View view) {
            startActivity(new Intent(getApplicationContext(), Bar.class));
            finish();
        }
    });
Sim Sun
  • 587
  • 1
  • 4
  • 28