Fragmentation on .NET LOH due to pinned objects

561 Views Asked by At

I'm troubleshooting an application written in .net 4.5 Asp.net + Unity 3.0.1304.1 + Nhibernate 3.3.1.4 that reaches 3 to 5 GB of memory consumption, which is above the expected.

After collecting some Memory Dumps it became clear there was fragmentation on the Large Object Heap.

My first thought was to update the application to .net 4.5.1 and tell GC to compact LOH, but it came to my attention the amount of Pinned Object Arrays, which led to a demo app where was possible to conclude that heap compaction was not helpful on the Pinned Objects scenario and is not even necessary when there is no pinned objects because there is no fragmentation.

So I tried to track this pinned objects and reached this question where it is said that static members are responsible for those pinned objects and that the handles are located on High Frequency Heap.

My questions are:

  • How can I proceed to try to solve the fragmentation problem?
  • How can I get more info about what is on High Frequency Heap since the commands I know from WinDbg do not work?

Above some prints from windbg:

  • Load Screen
  • Dumpheap Showing 618 free blocks
  • HeapStat Showing size and emptiness percentage on LOH
  • gch There are 76 Pinned Object Array, all in LOH
  • MRoot
  • mdt Content of one of the arrays
  • GCGen Showing that the arrays are indeed in LOH
1

There are 1 best solutions below

0
On

I recently solved a similar problem explained in this question: Large unexplained memory in the memory dump of a .NET process. Pinned objects were not in the High Frequency Heap but related to the async socket API. Note that the objects were byte[] thus probably not your case.

I don't think pinned objects in the High Frequency Heap can cause fragmentation. Because it's a separate heap. Your objects are on the LOH anyway.

So first, you need to identify what creates (and pins) these objects. Sadly I don't know of a simple method. You should try to identify the code creating or pinning these objects. The only way I have found in my case was running different parts of the code separately and create a dump for each... and I was lucky at some point. Maybe you can look at what pinning looks like. But it may happen in low level parts of the CLR.