LargeObjectHeapCompaction in .NET Garbage Collection

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.

Abhishek Sur

Abhishek Sur is a Microsoft MVP since year 2011. He is an architect in the .NET platform. He has profound theoretical insight and years of hands on experience in different .NET products and languages. He leads the Microsoft User Group in Kolkata named KolkataGeeks, and regularly organizes events and seminars in various places for spreading .NET awareness. He is associated with the Microsoft Insider list on WPF and C#, and is in constant touch with product group teams. He blogs at http://www.abhisheksur.com His Book : Visual Studio 2012 and .NET 4.5 Expert Development Cookbook. Follow Abhishek at Twitter : @abhi2434

One Comment to “LargeObjectHeapCompaction in .NET Garbage Collection”

Comments are closed.