Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How much GCHandle pinned memory/objects would make Garbage Collector slows down?

I'm sure this answer will depends the user machine, but there must be some best practices on pinning data.

I need to hold like 5 arrays of bytes containing 1.048.576 bytes each. Normally I would prefer to use GCHandle (managed) memory, but some people says it would slow down the GC. I know that can happen, but how much memory/objects need to be pinned to start to really affect the GC?

Here are the options that I have:

  1. GCHandle.Alloc GCHandleType.Pinned (managed). It will slow down GC??
  2. Marshal.AllocHGlobal (unmanaged acess). unsafe code
  3. use a Bitmap to hold data in Scan0 (unmanaged acess). unsafe code
like image 820
Pedro77 Avatar asked Jun 11 '13 12:06

Pedro77


People also ask

Why is garbage collection so slow?

One of the most misunderstood parts of garbage collection is that it doesn't actually collect dead or unused objects; it collects used ones, the so-called survivors. Garbage collection is slow if most objects survive the collection process.

Is GC collect slow?

GC is slow, mostly because it needs to pause program execution to collect garbage. Think of it like this — your CPU can only work on one thing at a time.

How can I speed up my garbage collection?

Short of avoiding garbage collection altogether, there is only one way to make garbage collection faster: ensure that as few objects as possible are reachable during the garbage collection. The fewer objects that are alive, the less there is to be marked. This is the rationale behind the generational heap.

How does a garbage collector reclaim memory?

When a garbage collection is triggered, the garbage collector reclaims the memory that's occupied by dead objects. The reclaiming process compacts live objects so that they are moved together, and the dead space is removed, thereby making the heap smaller.


1 Answers

This is a hopelessly unanswerable question. Pinned objects do not slow down the GC that much, it is just a rock in the road when the GC compacts the heap. Easy enough to work around that rock by simply skipping the pinned section of the heap.

The far worse outcome is that it will have a lasting effect on the code that runs after the collection is completed. Since the heap isn't compacted that well, the locality of references is not as good so the processor won't be able to get as much mileage from the CPU caches. Quantifying that slow-down isn't possible, it greatly depends on the kind of code that runs afterwards. Only that it is worse and lasts for a while, until the next GC.

The only good advice is that, if you have to pin, then do so for as short amount of time as possible. And to avoid scenarios where a collection may occur while an object is pinned. Which, roughly, means that you avoid allocating memory while holding the pin. Not always practical if the program is running multiple threads, making the <gcServer> element in the .config file attractive. Which selects a different GC strategy that uses a lot more memory but gives threads their own GC heap segments. There is no simple guidance to determine when to do this, profiling with realistic data sets is required.

Neither Marshal.AllocHGlobal nor Bitmap have any notable affect on the GC heap, they allocate from unmanaged memory heaps.

like image 187
Hans Passant Avatar answered Sep 22 '22 15:09

Hans Passant