FragmentStatePagerAdapter memory leak (nested fragments with viewpager)

JC. picture JC. · Dec 30, 2013 · Viewed 7.5k times · Source

I have a "memory leak" in my adapter (quotes will be explained later). I'm currently using nested fragments to host a viewpager.

My setup is as following:
1. Activity (Empty activity that hosts Fragment A)
2. Fragment A - fragment that hosts viewpager with Fragmentstatepageradapter. Each viewpager page hosts fragment B.
3. Fragment B - a fragment that contains an imageview.

Everything is working great except when a configuration change occurs. Monitoring the heap, it seems to grow by 100 kb everytime a rotation occurs. Manually GCing does not release the memory.

Things I've tried:
1. Replace Fragment B with a blank fragment - same issue occurs so it's not the imageview that's causing the issue.
2. Remove both fragment A and B and rotate the activity. No memory leak occurs so it's not the activity.
3. Used MAT before any orientation changes and after rotating about 50 times to get the heap up. MAT shows 1 major suspect which is my adapter class. It shows 7MB of retained heap (very small shallow heap) of observers like so:

array java.util.ArrayList @ 0x42079938 24 7,000,832 
.\mObservers android.database.DataSetObservable @ 0x42053508 16 7,000,848 
..\mObservable com.example.main.Adapter@ 0x4205a048 40 7,001,416 

Why I'm using a viewpager inside a fragment:
1. I want to keep the state of the adapter and other variables related to the viewpager alive by setting setretaininstance(true).
2. After a config change, I don't recreate the adapter but use the old one to attach to the viewpager.
3. If I don't reuse the old adapter but create a new adapter after a configuration change, the memory leak dissapears.
4. the memory leak also dissapears after i close the activity and return to the previous activity.

Any ideas? Would appreciate any help.

Thanks, JC

Answer

Carlos Castro picture Carlos Castro · Jan 7, 2014

I had a similar memory leak which is now resolved.

In my corresponding Fragment A, I was instantiating the FragmentStatePagerAdapter with this.getFragmentManager() instead of this.getChildFragmentManager() since nested fragments are in place.

Please let me know if this also fixes your issue.