When a Fragment is replaced and put in the back stack (or removed) does it stay in memory? When a Fragment is replaced and put in the back stack (or removed) does it stay in memory? android android

When a Fragment is replaced and put in the back stack (or removed) does it stay in memory?


Take a look at this: BackStackRecord.Op.fragment

That is how fragments are stored in the back stack. Note the live reference, neither WeakReference nor SoftReference are used there.

Now this: FragmentManagerImpl.mBackStack

That is where manager stores the back stack. Simple ArrayList, also, no WRs or SRs.

And finally this: Activity.mFragments

That is the reference to the fragment manager.

GC can only collect objects that have no live references (are not reachable from any thread). That means, until your Activity is destroyed (and so, FragmentManager reference is gone), GC will not be able to collect any of the Fragments in the back stack.

Note that when Activity is destroyed and retains state (like when you turn the device to landscape mode), it doesn't retain actual Fragment objects in the stack, only their states - Fragment.FragmentState objects, i.e. actual fragments in the back stack are re-created every time activity gets re-created with retained state.

Hope this helps.

PS So, in short: Yes, you can run out of memory by adding Fragments to back stack as well as by adding too many views to view hierarchy.

UPD Considering your example, F will stay in memory until C is killed. If C is killed and then resurrected with different configuration - F will be destroyed and reincarnated in a different object as well. So, F's memory footprint is around until C loses state or back stack is cleared.


I'm sorry for not being able to provide you with some official source of information, but I was curious too to see what would happen and decided to test it. And according to my tests, yes, you run the risk of running out of memory.

I had to add an incredible amount of Fragments (more than one hundred) in a for loop for the OutOfMemoryError to happen, but it did happen. And checking my logs, I could see that the onCreate() and onCreateView() methods were called a lot of times but onSaveInstance(), onPause() and onDestroy weren't called at all.

For reference, this is how I added the fragments to the backstack:

getSupportFragmentManager().beginTransaction().add(R.id.scene_fragment_container, mSceneFragment).addToBackStack("FOOBAR").commit();

And the Fragments I added were somewhat simple: an ImageView, an EditText, a couple TextViews, a SeekBar and a ListView.

But unless you are holding a huge amount of data in memory it shouldn't be an issue.

Later I tried adding only 50 to the backstack, killing the app and restarting it. And as I hoped/guessed, all the fragments were restored (and the onSaveInstance() and onPause() methods called) so my lifecycle implementation wasn't the issue that caused the OutOfMemoryError to fire.


From developer.android.com/guide/topics/fundamentals/fragments.html

A fragment must always be embedded in an activity and the fragment's lifecycle is directly affected by the host activity's lifecycle. For example, when the activity is paused, so are all fragments in it, and when the activity is destroyed, so are all fragments. However, while an activity is running (it is in the resumed lifecycle state), you can manipulate each fragment independently, such as add or remove them. When you perform such a fragment transaction, you can also add it to a back stack that's managed by the activity—each back stack entry in the activity is a record of the fragment transaction that occurred. The back stack allows the user to reverse a fragment transaction (navigate backwards), by pressing the BACK button.