Garbage collection in .NET (generations) [closed]
Asked Answered
W

3

23

I have read a lot of .NET performance articles that describe Gen1,Gen2 garbage collection and objects surviving the generations.

Why does objects survives the collection?

What is pinning?

Waylen answered 11/6, 2009 at 0:4 Comment(1)
You get a copy of CLR via C# and read through the Chapter on Garbage collection. It is a slightly meaty topic - to learn off an online forum.Halting
Y
31

One reason you have multiple generations in a garbage collector is to avoid losing memory to fragmentation.

Every function call can mean the creation and deletion collection of multiple objects, and so the memory heap for your program tends to fragment very quickly. This leaves holes behind that aren't very usable. The result is that your program needs to be periodically de-fragmented, just like a hard disk. This is part of what happens during a collection.

When an object survives a collection, it is moved to a longer-lived generation on the theory that if it survived one collection it will probably survive others. Thus the later generations have less turn-over and don't fragment as much. This means your program spends less time overall juggling things around to clean up holes and wastes less memory. This is also an improvement over traditional memory management (malloc/free or new/delete), which left it up to the operating system to manage any memory fragmentation.

The reason an object survives collection is because there is something somewhere that is still "in scope" and holds a reference to that object. There are a few ways you can cause this to happen and then forget about the reference, so it is possible to "leak" memory in managed code.

Sometimes people are tempted to call GC.Collect() in an effort to get the garbage collector to clean something up. Perhaps they've discovered they have a leak, or think memory is becoming over-fragmented. You should resist those urges. While garbage collection in .Net is not perfect, is it very good, and it's almost certainly much better at cleaning up memory than you are. Odds are that if an object can and should be collected, it will be. Remember that calling GC.Collect() can actually make things worse by helping the garbage collector move objects up to a higher generation, and thus keeping them around for longer than they otherwise would be.

Instead, if you suspect you have a leak, look to your own code for something like a global or static variable that might hold a reference to a lot of other items. The only time you should call GC.Collect() is when you have information about the nature of the program that is not available to the garbage collector, and that's pretty rare as the GC knows every reference you've created.

"Pinning" is for when you need to pass an object to an unmanaged library. The garbage collector can move an object's physical location in memory, and so you need to "pin" it in one place or the pointer used by the unmanaged library could become invalid. A pinned object cannot be collected, and so you shouldn't pin an object for any longer than necessary.

Yasmeen answered 11/6, 2009 at 0:4 Comment(7)
when you say GC in .NEt is not perfect, what are the things you don't like about it, I am interested to know since this helps us impove it. ThanksGoodale
Nothing in particular - from your profile description I suspect you know a lot more about it than I do. I say "not perfect" in the sense that "nothing is perfect" and it's as fallible as any software - if you really want to break it you can find a way.Yasmeen
Updated the post so that line doesn't stand out so much... this is slowly working itself into a longer answer.Yasmeen
I agree with you from this perspective:), however nothing is perfect in the world:), so it is a general statment and not particular to the GC:)Goodale
@mfawzymkh: My biggest complaint about the GC is that large objects go into the Large Object Heap. This effectively promotes to level 2 any smaller objects to which a large object holds references. Further, there are some scenarios where the large object can become very fragmented. Would there be any particular problem with allocating LOH objects in 4K blocks, and/or with adding another generation to the LOH? Since the smallest LOH objects are 85K, rounding up to 4K would be at most a 5% memory hit. And while LOH objects may be expensive to GC, they're also expensive not to GC.Afroamerican
@Afroamerican - I'd just like to see it try to defrag the LOH before throwing an OutOfMemoryException.Yasmeen
@Joel Coehoorn: Sounds like a good idea to me. I understand a desire to not defrag the LOH on every cleanup, since such a defrag would be expensive. I can't imagine it being more expensive than a crash, though.Afroamerican
G
10

http://blogs.msdn.com/maoni/ is a good resource.
Asking questions here helps too :)

For your questions:

Why do objects survive the collection:
Objects survive a collection when they are "live objects", or "Reachable objects". Reachable objects are objects where there is a reference to them from another object that is on:

  1. The stack
  2. The finalization queue
  3. another object in a higher generation ( for example a Gen2 Object holding a reference to a Gen0 Object )
  4. The handle table ( a data structure used by the CLR, and require a seperate post on its own:) )

What is Pinning:
Pinning means making sure the object doesn't move in memory. objects move in memory as a result of a compacting GC, you can create a GCHandle of typed pinned if you want to pin an object, pinning also happens automatically behind the sciene for objects that are passed to native code via PInvoke ( like strings that are passed as output, the internal buffer gets pinned during the call to PInvoke ).

Check out http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.gchandle.aspx for a good example about GCHandle.

Goodale answered 11/6, 2009 at 0:14 Comment(2)
For my own enlightment: Would it be correct to say that "pinned" objects live on the handle table?Yasmeen
:) When you create a GCHandle, it is stored in the handle table, which is used as one of the sources to find out about live objects. so Pinned and non pinned GCHandle are stored there.Goodale
I
0

Pinning is used to keep the garbage collector from relocating objects. It can hurt performance by restricting what the garbage collector can do. In general pinned objects should be pinned for as short as time as possible.

Impuissant answered 11/6, 2009 at 0:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.