Reputation: 151
I'm preparing a presentation to my team on .net GC and memory. Different sources discuss the potential impact of fragmentation on Large Object Heap. Since it would be an interesting phenomenon to show, I'm trying to show that in code.
Thomas Weller offered this code which looks like it should cause OOM when trying to allocate a larger object into the freed gaps in LOH but for some reason it doesn't occur. Is LOH being compacted automatically in .net 4.6? Is LOH fragmentation simply not an issue in 64bit?
source: https://stackoverflow.com/a/30361185/3374994
class Program
{
static IList<byte[]> small = new List<byte[]>();
static IList<byte[]> big = new List<byte[]>();
static void Main()
{
int totalMB = 0;
try
{
Console.WriteLine("Allocating memory...");
while (true)
{
big.Add(new byte[10*1024*1024]);
small.Add(new byte[85000-3*IntPtr.Size]);
totalMB += 10;
Console.WriteLine("{0} MB allocated", totalMB);
}
}
catch (OutOfMemoryException)
{
Console.WriteLine("Memory is full now. Attach and debug if you like. Press Enter when done.");
Console.WriteLine("For WinDbg, try `!address -summary` and `!dumpheap -stat`.");
Console.ReadLine();
big.Clear();
GC.Collect();
Console.WriteLine("Lots of memory has been freed. Check again with the same commands.");
Console.ReadLine();
try
{
big.Add(new byte[20*1024*1024]);
}
catch(OutOfMemoryException)
{
Console.WriteLine("It was not possible to allocate 20 MB although {0} MB are free.", totalMB);
Console.ReadLine();
}
}
}
}
Upvotes: 5
Views: 2116
Reputation: 143
My guess is, LOH will not be compact automatically.
Since compact LOH impact to performance, we should do it when we know it for sure.
With this code, it will run out memory very soon, the compact action only recycle object that did not referenced
Upvotes: 1
Reputation: 2806
Since .NET 4.5.1 (also .NET Core) LOH compaction is supported and the behavior could be set by the GCSettings.LargeObjectHeapCompactionMode
property of the static class GcSettings.
This means, the LOH is compacted by the GC.
Be aware of that a 32bit process has some limitation on how much memory could be used, therefore it is more likely to run into a OOM exception.
Upvotes: 3