Many moons ago I made a post on When does the .NET Compact Framework Garbage Collector run. Given that a lot of things have changed since then, it’s time to make another post about the same thing.
For the developers coming to Windows Phone 7 (WP7) from the Windows desktop let me first clarify that the runtime (CLR) that is running on the WP7 is not the same as the one running on the desktop. The WP7 runtime is known as .NET Compact Framework (NETCF) and it works differently than the “desktop CLR”. For 90% of cases this is irrelevant as the WP7 developer targets the XNA or Silverlight programming model and hence what is running underneath is really not important. E.g when you drive you really do not care about the engine. This post is for the other 5% where folks do run into issues (smoke coming out of the car).
Moreover do note that when the GC is run is really an implementation detail that is subject to change.
Now that we have all the disclaimers behind us lets get down to the list.
The Garbage Collector is run in the following situations
- After some significant allocation:
When an application tries to allocate managed memory the allocator first checks a counter that indicates the number of bytes of managed data allocated since the last GC. If this counter crosses a threshold (which is changeable and set to 1MB currently) then GC is fired (and the counter is obviously reset).
The basic idea is that there has been significant allocation since the last GC and hence do it again.
- Resource allocation failure
If some internal native allocation fails, like loadlibrary fails or JIT buffer allocation fails due to out-of-memory condition then GC is started to free up some memory and the allocation is re-attempted (only 1 re-attempt)
- User code can trigger GC
Using the managed API System.GC.Collect(), user code can force a GC
- Sharing server initiated
One of the new features in the WP7 CLR is the sharing server (see my post http://blogs.msdn.com/b/abhinaba/archive/2010/04/28/we-believe-in-sharing.aspx for details). In WP7 there is a central server coordinating all the managed processes. If this sharing server is notified of low memory condition, it starts GC in all the managed processes in the system.
The GC is NOT run in the following cases (I am explicitly calling these out because in various conferences and interactions I’ve heard folks thinking it might be)
- GC is not run on some timer. So if a process is not allocating any memory and there is no low-memory situation then GC will never be fired irrespective of how long the application is running
- The phone is never woken up by the CLR to run GC. GC is always in response to an active request OR allocation failure OR low memory notification.
- In the same lines there is no GC thread or background GC on WP7
For folks migrating from NETCF 3.5 the list below gives you the changes
- WinForm Application going to background used to fire GC. On WP7 this is no longer true
- Sharing server based changes are obviously new
- The GC quantum cannot be changed by user