Do you know that .NET GC
now equipped with yet another option to Compact Large Object Heap
. This has been a long problem for people where LOH can produce fragmentation in memory or when Free space table cannot handle allocation requests. LOH is the Large object Heap allocated generally for large objects which are above 85,000 bytes long. The number has been considered as a result of performance tuning. When object allocation requests are made above this threshold, the object is allocated in LOH.
The common problem with LOH is that, it rarely gets GCed, and it GC only when the GC 3 gets executed. But even though the GC deal locates the memory from the Heap, and there is a special concept of Free Space Table which stores the Pointers of the Free spaces, there could always be fragmentation present on the HEAP because of no Heap Compaction. With the exception to double arrays, which goes to Heap only at 8000 bytes rather than 85,000 the problem becomes more prominent in large production environments.
From the former declaration, LOH compaction has never been performed because LOH are large allocations and pointer mathematics on the LOH compaction can produce havoc performance penalties. The previous Concurrent GC suspends the Execution Engine(EE)
which results in certain block on execution of the process. With large fragmentation in LOH memory, the Compaction can really kill performance for a server.
With the recent introduction of Background GC which is more recommended for Server operating systems, GC becomes non-blocking and hence LOH compaction can be performed with EE remains active.
GCSettings
now allows you to Compact the LOH segement of memory as well. This option may come very handy when there are large fragmentation in memory in production servers as a result of large number of GC 2 being executed and LOH has been deallocated. As an application developer you can now easily call :
GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce; GC.Collect();
This will Compact the LOH when the next Full GC is performed. With GC.Collect
call after the settings been applied, the GC gets compacted immediately.
For a workstation, I would recommend to restart the process when you really require Heap Compaction, but for Servers running day and night, this option might come handy.
I hope this post will help you.
You can find more about hidden secrets of Memory Management in my book (NET 4.5 Expert Development Cookbook)
Thanks for reading.
Pingback: Benefit of Using in Dispose for .NET objects (Why and When ?)