I wrote a long TCP connection socket server in C#. Spike in memory in my server happens. I used dotNet Memory Profiler(a tool) to detect where the memory leaks. Memory Profiler indicates the private heap is huge, and the memory is something like below(the number is not real,what I want to show is the GC0 and GC2's Holes are very very huge, the data size is normal):
Managed heaps - 1,500,000KB
Normal heap - 1400,000KB
Generation #0 - 600,000KB
Data - 100,000KB
"Holes" - 500,000KB
Generation #1 - xxKB
Data - 0KB
"Holes" - xKB
Generation #2 - xxxxxxxxxxxxxKB
Data - 100,000KB
"Holes" - 700,000KB
Large heap - 131072KB
Large heap - 83KB
Overhead/unused - 130989KB
Overhead - 0KB
Howerver, what is GC hole? dotNet Memory Profiler's documention definite the "Holes":
“Holes” represent memory that is unused between two allocated instances. “Holes” appear when the heap is not fully compacted, due to pinned instances or optimizations in the garbage collector.
What I want to know is:
I hope somebody can explain it.
A pinned object is one that is not allowed to move in memory. This is often needed when working with unmanaged code which requires that you pass in a pointer to some structure in memory - by default the garbage collector is free to move that structure around in order to best manage memory, however if it does this when you've given some unmanaged code a pointer to that structure then if its moved that unmanaged code won't be pointing to the correct structure any more, leading to unexpected behaviour.
The solution is to "pin" that object to tell the GC that it shouldn't move it.
You can't explicitly compact the heap, the GC should so this itself when performing either a full or partial collect (with the exception of the LOH) - pinning lots of objects will make it harder for it to successfully manage this however. For more detail on the GC see Garbage Collector Basics and Performance Hints
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With