Recently I was in a conversation about memory usage on the Windows Phone. The conversation turned to the Phone back stack and the question became, “what is stored on the back stack?” So I created a very simple application; MainPage.xaml allows the user to select and show a picture. It also contains a link to Page1.xaml. Page1 displays a count of the back stack plus a simple view model that contains a large chunk of dummy data and a creation timestamp. It also has a link to MainPage.xaml. To be clear, there is no code that reloads or stores/restores state, everything is creating either in the constructor or from user input. This allowed me to create a test with the following stack;
MainPage.xaml (pic1) –> Page1.xaml (Count=1) –> MainPage (pic2) –> Page1.xaml (Count=3), etc.
The results show that EVERYTHING is stored on the stack, user selected pictures, view models, everything . As you move back through the stack all the pictures and the old timestamps are all correctly displayed. The only limit on how big the stack can grow is the memory ceiling.
Resume and Tombstoned
Any Windows Phone developer will know the story isn’t as simple as that, what about Resume and Tombstone? If you have travelled through a number of pages and press the Windows key then your app will be deactivated. If you switch back to your app and the OS has allowed you to Resume then all of the state will be ready for you. The implication here is that your entire apps memory footprint can be hanging around until the OS decides you no longer want it. However, if your application is Tombstoned then only the navigation URI history is automatically retained. Consider the following stack with the selected picture and the view model timestamp;
Main Page (pic1) –> Page 1 (T1) –> Main Page (pic2) –> Page 1 (T2)
With a successful Resume you will be able to back-through the application and get;
Page 1 (T2) –> Main Page (pic2) –> Page 1 (T1) –> Main Page (pic1) –> Close
However, if your app is Tombstoned you will get;
Page 1 (T3) –> Main Page (empty) –> Page 1 (T4) –> Main Page (empty) –> Close
Therefore under Tombstoned conditions it is up to you to store and restore any state you wish to present to the user or even remove the back stack if that makes more sense.
If your application allows an ‘infinite’ stack to form then you should worry about the memory implications and consider using a strategy that will either/or prevent the stack growing too large or clear up resources as you navigate away from a page.
(Edit) What happens when you back-out through the stack?
One thing I didn’t mention was when are the pages fully destroyed? As you move away from a page (in either direction) the page unload is called, but the underlying object remains. As you move back through the stack the page objects are reclaimed. This will not necessarily happen immediately, but you should eventually see the destructors called for pages.