NETCF: GC and thread blocking
One of our customers asked us a bunch of questions on the NETCF garbage collector that qualifies as FAQ and hence I thought I’d put them up here.
Question: What is the priority of the GC thread
Answer: Unlike some variants of the desktop GC and other virtual machines (e.g. JScript) we do not have any background or timer based GC. The CLR fires GC on the same thread that tried allocation and either the allocation failed or during pre-allocation checks the CLR feels that time to run GC has come. So the priority of the GC thread is same as that of the thread that resulted in GC.
Question: Can the GC freeze managed threads that are of higher priority than the GC thread?
Answer: Yes GC can freeze managed threads which has higher priority than itself. Before actually running GC the CLR tries to go into a “safe point”. Each thread has a suspend event associated with it and this event is checked by each thread regularly. Before starting GC the CLR enumerates all managed threads and in each of them sets this event. In the next point when the thread checks and finds this event set, it blocks waiting for the event to get reset (which happens when GC is complete). This mechanism is agnostic of the relative priority of the various threads.
Question: Does it freeze all threads or only Managed threads?
Answer: The NETCF GC belongs to the category “stop-the-world GC”. It needs to freeze threads so that when it is iterating and compacting managed heap nothing on it gets modified. This is unlike some background/incremental GC supported by other virtual machines.
GC freezes only managed threads and not other native threads (e.g. COM or host-threads). However, there are two exclusions even on the managed threads
- It doesn’t freeze the managed thread that started GC because the GC will be run on that thread (see answer to first question)
- Managed threads that are currently executing in native p/invoke code is not frozen either. However, the moment they try to return to managed execution they get frozen. (I actually missed this subtle point in my response and Brian caught it :))
Hope this answers some of your questions. Feel free to send me any .NET Compact Framework CLR questions. I will either answer them myself or get someone else to do it for you :)
Comments
- Anonymous
October 31, 2013
I am concerned on a test that we performed on a .NET 4.0 based app, though it is compiled for 'anycpu' and was run on 64-bit W2k8. I observed tremendous increase in response times when we increased the load. Secondly, I observed that the app is not growing beyond 2GB RAM. I see # contentions increasing rapidly. I also see % time in GC is growing. We have 16GB RAM and 4 CPUs. What else I need to do in order to improve response times? Thanks in advance.