No More Memory Fragmentation on the .NET Large Object Heap
There are two different "types" of heaps in .NET. The Small Object Heap (SOH) and the Large Object Heap (LOH). One of the key differences between the heaps is that the SOH compacts memory and hence reduces the chance of memory fragmentation dramatically while the LOH does not employ compaction. As a result, excessive usage of the LOH may result in memory fragmentation that can become severe enough to cause problems in applications. In order to avoid potential memory fragmentation on the LOH, developers can use various techniques that involve writing additional code. With the advent of the newly released .NET Framework 4.5.1 (Preview), developers can now tell the CLR (garbage collector) to compact the LOH thereby avoiding memory fragmentation.
.NET 4.5.1 Preview now includes a new enumeration called GCLargeObjectHeapCompactionMode that has two fields:
- CompactOnce - The next time a full GC occurs the LOH will be compacted. Once done, it reverts back to the default behavior which is non compacting.
- Default - Default behavior is non compacting.
In order to set the LOH compaction mode using the enum above, simply use the GCSettings class and its corresponding LargeObjectHeapCompactionMode property:
GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce;
GC.Collect(); // This will cause the LOH to be compacted (once).
The .NET 4.5.1 Preview can be downloaded from: https://www.microsoft.com/visualstudio/eng/2013-downloads
As always, please note that this is a Preview release and as such functionality and behavior is subject to change.
Comments
Anonymous
July 02, 2013
Is this the proper way to invoke this when we're not sure we're running on .NET4.5.1? var piLOHCM = tGCSettings.GetProperty("LargeObjectHeapCompactionMode", BindingFlags.Static | BindingFlags.Public); if (null != piLOHCM ) { var miSetter = piLOHCM.GetSetMethod(); miSetter.Invoke(null, new object[] { /* GCLargeObjectHeapCompactionMode.CompactOnce */ 2 }) GC.Collect(); // This will cause the LOH to be compacted (once). }Anonymous
November 16, 2013
Why would you not know what .NET you are running on? You have to compile your app against 4.5.1 duhAnonymous
January 16, 2014
B, I might be wrong but i think If you are building libraries, it is possible you might not know the version of .Net framework you are running on because the client application can choose to use a different version of .Net framework using the supportedRuntime tag in app.config fileAnonymous
February 10, 2015
If you're building libraries, your library shouldn't be doing LOH garbage collection. Your library should not be causing LOH fragmentation. This is something the application that is having the issue (due to bad libraries or their own code) might need to do.