Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

This question concerns memory in Android.

My method:

I have two activites, A and B. From A, I launch B like this:

Intent i = new Intent(A.this, B.class);
startActivity(i);

On button click in B, I do this:

B.this.finish();
  • In B, I override the onDestroy method and set all references to null.
  • I do not allocate new memory in the onResume method of A.
  • I am not leaking a context.
  • I am not using multiple threads.
  • I am not using services.
  • All variables in B are private class variables, and all of them are set to null in the onDestroy of B.
  • Also, ImageViews in B have their background set null in the onDestroy of B.
  • I am certain that B gets destroyed.

The result:

When I am in Activity A, heap memory is at 7.44 MB. Then when I start B and call finish on B(and thus returning to A), heap is increased by 0.16 MB. Repeating this process again, heap is increased by 0.08 MB every time.

  • I'm not looking at the heap limit, I'm looking at the allocated heap.
  • I'm calling System.gc() at the end of the onDestroy method of B.

Additional info:

-I have used MAT to analyse memory allocations and try to find this leak. Something strange is that Activity B seems to have 5 instances. As it so happens, I was repeating the startActivity/finish process 5 times. The bottom entry is the Activity, the others are listeners in the activity:

enter image description here

And this is screenshot of the dominator tree. I can't find anything unusual or suspect.

Dominator Tree

-I have watched both google IO videos on memory usage(and leaks).

Question:

Is it possible that this 0.08 MB of heap will always be allocated(and not collectable by the GC) no matter what I do? If not, any idea of what might be causing this?

Update:

  1. I tried to launch activity B without setting a content view in B. This means that B is a completely empty activity. The result was that the heap memory did NOT increase when I'm relaunching the activity several times. Note, however, that this is no solution. I must be able to set a content view.

  2. scorpiodawg: I tried running my app on an emulator, and the heap still grows. Good try though.

  3. ntc: I changed all occurences of "this" to "getApplicationContext()" where it was possible. I could not call setContentView(getApplicationContext()); because setContentView wants a reference to a layout file, not a context. What I did instead was to create an empty layout file and call setContentView(emptylayout); in the onDestroy method of Activity B. That did not help.

  4. I tried to remove all the code so that only setContentView(mylayout) gets called. Problem persisted. Then I removed all the gui elements in the layout XML file. Problem persisted. The only thing that was left was the container views, a couple of nested linear, relative and scrolllayouts. I tried to remove setting the "android:scrollbarDefaultDelayBeforeFade" attribute in the scrollbar. The result was great, the memory leak had vanished. Then I put back all the code I previously removed but didn't set the "android:scrollbarDefaultDelayBeforeFade" attribute and the memory leak was back. How strange is that?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
153 views
Welcome To Ask or Share your Answers For Others

1 Answer

If you have 5 instances of activity B, then you are not managing the activity stack correctly. I find the best way to check it is with the CLI command:

adb shell dumpsys meminfo 'your apps package name'

I had a similar problem in a two activity project when I switched between them. Every time I switched I got a new instance on the stack as revealed by the above command. I then set the flags for the launched activities to FLAG_ACTIVITY_REORDER_TO_FRONT with code like:

Intent i = new Intent("com.you.yourActivityB");
i.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
startActivity(i);

Once I'd done this, then the adb shell command did not show more instances of my two activities when I switched between them


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...