{"id":23151,"date":"2005-10-04T02:30:00","date_gmt":"2005-10-04T02:30:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/maoni\/2005\/10\/04\/so-whats-new-in-the-clr-2-0-gc\/"},"modified":"2021-10-04T16:38:19","modified_gmt":"2021-10-04T23:38:19","slug":"so-whats-new-in-the-clr-2-0-gc","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/dotnet\/so-whats-new-in-the-clr-2-0-gc\/","title":{"rendered":"So, what\u2019s new in the CLR 2.0 GC?"},"content":{"rendered":"<p><P class=\"MsoNormal\"><FONT face=\"Verdana\" size=\"2\">Certainly that\u2019s one of the most frequently asked questions I get (at the PDC too!). So since PDC already happened I can tell the rest of you about the new stuff happened in GC in CLR 2.0. The slides can be downloaded <\/FONT><A href=\"http:\/\/216.55.183.63\/pdc2005\/slides\/FUN421_Stephens.ppt\"><FONT face=\"Verdana\" size=\"2\">here<\/FONT><\/A><FONT face=\"Verdana\" size=\"2\">. And I will be referring to some of the slides. I must apologize for your having to click on the link to see the slide each time I refer to one since I don\u2019t have a separated site where I can store pictures.<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Verdana\" size=\"2\"><\/FONT>&nbsp;<\/P>\n<P class=\"MsoNormal\"><FONT size=\"2\"><FONT face=\"Verdana\">Most of what I am going to talk about was covered in my PDC GC talk. BTW, just a few words about the 2005 PDC (skip this paragraph if you are interested in only technical stuff \ud83d\ude42<\/FONT><FONT face=\"Verdana\">). I was very pleased with the way it went. I got to talk to lots of customers who told me how awesome our GC was which certainly made me feel very good! There were a couple of customers who did tell us about the problems they had with our GC. One problem we already addressed in Whidbey and the other one was something we were perfectly aware of and had put on our todo list. So no surprises there. I was happy to see the number of people at my talk considering it was the latest possible and lots of people had already left the conference before that. So all in all it was great.<\/FONT><\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Verdana\" size=\"2\"><\/FONT>&nbsp;<\/P>\n<P class=\"MsoNormal\"><FONT face=\"Verdana\" size=\"2\">Some terminology before we start:<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Verdana\" size=\"2\"><\/FONT>&nbsp;<\/P>\n<P class=\"MsoNormal\"><FONT size=\"2\"><FONT face=\"Verdana\"><I>Ephemeral generations<\/I> \u2013 gen0 and gen1.<\/FONT><\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Verdana\" size=\"2\"><\/FONT>&nbsp;<\/P>\n<P class=\"MsoNormal\"><FONT size=\"2\"><FONT face=\"Verdana\"><I>Ephemeral segment<\/I> \u2013 the segment that gen0 and gen1 live in (they always live in one segment) and there can only be one ephemeral segment for each heap. So for server GC, if we have 4 heaps we have 4 ephemeral segments (refer to my <\/FONT><\/FONT><a href=\"http:\/\/blogs.msdn.com\/maoni\/archive\/2004\/09\/25\/234273.aspx\"><FONT face=\"Verdana\" size=\"2\">Using GC Efficiently \u2013 Part 2<\/FONT><\/A><FONT face=\"Verdana\" size=\"2\"> for explaination for different flavors of GCs).<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Verdana\" size=\"2\"><\/FONT>&nbsp;<\/P>\n<P class=\"MsoNormal\"><FONT face=\"Verdana\"><FONT size=\"2\"><I>Small object heap<\/I> \u2013 you know LOH (if you don\u2019t, it\u2019s covered in <\/FONT><\/FONT><a href=\"http:\/\/blogs.msdn.com\/maoni\/archive\/2004\/06\/15\/156626.aspx\"><FONT face=\"Verdana\" size=\"2\">Using GC Efficiently \u2013 Part 1<\/FONT><\/A><FONT size=\"2\"><FONT face=\"Verdana\">), so the rest of the managed heap is called small object heap \ud83d\ude42<\/FONT><\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT size=\"2\"><SPAN><SPAN><\/SPAN><\/SPAN><\/FONT>&nbsp;<\/P>\n<P class=\"MsoNormal\"><FONT size=\"2\"><SPAN><SPAN><\/SPAN><\/SPAN><\/FONT><B><FONT size=\"2\"><FONT face=\"Verdana\">Fragmentation control<\/FONT><\/FONT><\/B><\/P>\n<P class=\"MsoNormal\"><STRONG><FONT face=\"Verdana\" size=\"2\"><\/FONT><\/STRONG>&nbsp;<\/P>\n<P class=\"MsoNormal\"><FONT face=\"Verdana\" size=\"2\">If you ask me what was the most significant improvement in the CLR 2.0 GC from the 1.1 GC, I\u2019d have to say it\u2019s the work we did in reducing fragmentation caused by pinning.<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Verdana\" size=\"2\"><\/FONT>&nbsp;<\/P>\n<P class=\"MsoNormal\"><FONT face=\"Verdana\" size=\"2\">One of the biggest problems we faced for managed applications was wasted free space on the managed heap. And sometimes you get OOM while there\u2019s plenty of free space on the managed heap. So reducing fragmentation, in other words, having less space wasted on the managed heap, was crucial. It was observed often in applications that perform IO which needs to pin the buffers for the native APIs to read or write to them. As such, we\u2019ve done a lot of work in CLR 2.0 to help solve this <\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Verdana\" size=\"2\">problem.<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Verdana\" size=\"2\"><\/FONT>&nbsp;<\/P>\n<P class=\"MsoNormal\"><A href=\"http:\/\/216.55.183.63\/pdc2005\/slides\/FUN421_Stephens.ppt#351,25,Slide 25\"><FONT face=\"Verdana\" size=\"2\">Slide 25<\/FONT><\/A><FONT face=\"Verdana\" size=\"2\"> demonstrates the fragmentation problem caused by pinning. Let\u2019s say we have an application where each request performs some type of socket or file IO. Before GC number X we have a heap that has one segment, which is our ephemeral segment, has bunch of stuff allocated in gen0, including some pinned objects. Now a GC is triggered. After the collection what survived from gen1 was promoted to gen2. For a simplistic view let\u2019s just say nothing from gen0 except the pins survived. In reality what survived is the pinned objects and the other data associated with the requests that pinned those objects for this scenario. So after the collection, gen1 just has the pins \u2018cause that\u2019s all that survived from gen0. Gen0 then starts right after the 2<SUP>nd<\/SUP> pin.<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Verdana\" size=\"2\"><\/FONT>&nbsp;<\/P>\n<P class=\"MsoNormal\"><FONT face=\"Verdana\" size=\"2\">You can imagine that if this process keeps repeating itself, and let\u2019s say that the pins survived N more GCs, after these GCs we may have a situation where we have expanded the heap and the old ephemeral segment now is a gen2 segment and we acquired a new ephemeral segment. Again we start the new gen0 after the pins in the ephemeral segment.<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Verdana\" size=\"2\"><\/FONT>&nbsp;<\/P>\n<P class=\"MsoNormal\"><FONT face=\"Verdana\" size=\"2\">This is a really bad situation because we now have lots of wasted space on our heap. Both our gen2 and gen1 look quite empty. Obviously the less wasted space we can make it, the better.<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Verdana\" size=\"2\"><\/FONT>&nbsp;<\/P>\n<P class=\"MsoNormal\"><FONT face=\"Verdana\" size=\"2\">The fragmentation reduction work can be categorized into 2 things: one is called <I>demotion<\/I> which is to prevent fragmentation from getting into higher generation as much as we can; the other one is <I>reusing existing gen2 segments<\/I> so we can reuse the free space that has already made into gen2. Let\u2019s talk about them in more details.<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Verdana\" size=\"2\"><\/FONT>&nbsp;<\/P>\n<P class=\"MsoNormal\"><FONT face=\"Verdana\" size=\"2\">Demotion, as the opposite of promotion, means the object doesn\u2019t end up in a generation that it\u2019s supposed to be in. Imagine if after the compaction, there\u2019s plenty of space between some pinned objects at the end of the ephemeral segment, it\u2019s more productive to leave them in gen0 instead of promoting them to gen1 because when allocation requests come in the free space before the pins can be used to satisfy allocations. This is demonstrated with <\/FONT><A href=\"http:\/\/216.55.183.63\/pdc2005\/slides\/FUN421_Stephens.ppt#361,26,Slide 26\"><FONT face=\"Verdana\" size=\"2\">slide 26<\/FONT><\/A><FONT face=\"Verdana\" size=\"2\">.<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Verdana\" size=\"2\"><\/FONT>&nbsp;<\/P>\n<P class=\"MsoNormal\"><FONT face=\"Verdana\" size=\"2\">Segment reuse is relatively straightforward. It\u2019s to take advantage of the existing gen2 segments that have a lot free space but not yet empty (because if they were empty they would have been deleted). <\/FONT><A href=\"http:\/\/216.55.183.63\/pdc2005\/slides\/FUN421_Stephens.ppt#352,27,Slide 27\"><FONT face=\"Verdana\" size=\"2\">Slide 27<\/FONT><\/A><FONT face=\"Verdana\" size=\"2\"> demonstrates the problem without segment reuse. So before GC we are running out of space in the ephemeral segment and we need to expand the heap. We have 2 pinned objects. And I didn\u2019t mark their generations because it\u2019s not significant to indicate their generations &#8211; they can not be moved so they will stay in this segment and become gen2 objects by definition. There might be pinning on the gen2 segments as well but since that doesn\u2019t affect illustrating the point I preferred to keep the picture simple and left them out.<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Verdana\" size=\"2\">So after GC we allocate a new segment. The old gen1 in the old ephemeral segment was promoted to gen2 and the old gen0 now lives in the new ephemeral segment as the new gen1 and we will start allocating after gen1 on this segment. The pinned objects are left in the old ephemeral seg since they can not be moved. They are part of gen2 now because they live in a gen2 segment.<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Verdana\" size=\"2\"><\/FONT>&nbsp;<\/P>\n<P class=\"MsoNormal\"><A href=\"http:\/\/216.55.183.63\/pdc2005\/slides\/FUN421_Stephens.ppt#354,28,Slide 28\"><FONT face=\"Verdana\" size=\"2\">Slide 28<\/FONT><\/A><FONT face=\"Verdana\" size=\"2\"> demonstrates segment reuse. Same picture for before GC. During GC we found that segment 3 is empty enough so instead of allocating a new segment we decide to reuse this segment as the new ephemeral seg. The old ephemeral segment becomes a gen2 segment \u2013 as we said there can only be one ephemeral segment \u2013 and seg3 becomes the new ephemeral segment. The old gen0 now lives in this segment as the new gen1 and again, we start allocating in gen0 after that.<\/FONT><\/P>\n<P class=\"MsoNormal\">&nbsp;<\/P>\n<P class=\"MsoNormal\"><B><FONT size=\"2\"><FONT face=\"Verdana\">Fixed premature OOM bugs<\/FONT><\/FONT><\/B><\/P>\n<P class=\"MsoNormal\"><STRONG><FONT face=\"Verdana\" size=\"2\"><\/FONT><\/STRONG>&nbsp;<\/P>\n<P class=\"MsoNormal\"><FONT face=\"Verdana\" size=\"2\">Premature OOM means you have lots of free space yet you are getting an OOM exception. As I said above, having fragmentation can be a form of premature OOM because you can get OOM while you still have lots of free space on your managed heap. Besides that we also fixed some other premature OOM bugs so if you were getting premature OOM I say definitely try CLR 2.0 out if possible. The premature OOM bugs included bugs for both large and small object heap.<\/FONT><\/P>\n<P class=\"MsoNormal\">&nbsp;<\/P>\n<P class=\"MsoNormal\"><B><FONT size=\"2\"><FONT face=\"Verdana\">VM hoarding<\/FONT><\/FONT><\/B><\/P>\n<P class=\"MsoNormal\"><STRONG><FONT face=\"Verdana\" size=\"2\"><\/FONT><\/STRONG>&nbsp;<\/P>\n<P class=\"MsoNormal\"><FONT face=\"Verdana\" size=\"2\">First of all, this is a feature I would recommand you to <I>not<\/I> use unless absolutely necessary. The reason we added this feature was for 2 situations \u2013 one is when segments are created and deleted very frequently. If you simply can not avoid this, you can specify the VM hoarding feature which instead of releasing the memory back to the OS it puts the segment on a standby list. Note that we don\u2019t do this for the segments that are larger than the normal segment size (generally this is 16MB, for server GC the segments are larger). We will use these segments later to satisfy new segment requests. So next time we need a new segment we will use one from this standby list if we can find one that\u2019s big enough.<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Verdana\" size=\"2\"><\/FONT>&nbsp;<\/P>\n<P class=\"MsoNormal\"><FONT face=\"Verdana\" size=\"2\">This feature is also useful for apps that worry about fragmenting the VM space too much and want to hold onto the segments that they already acquired, like some server apps that need to frequently load and unload small DLLs and they want to keep what they already reserved so the DLLs don\u2019t fragment VM all over the place.<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Verdana\" size=\"2\">Since the feature should be used very conservatively it\u2019s only available via hosting API \u2013 you can turn it on by specifying the STARTUP_HOARD_GC_VM flag.<\/FONT><\/P>\n<P class=\"MsoNormal\">&nbsp;<\/P>\n<P class=\"MsoNormal\"><FONT face=\"Verdana\" size=\"2\">That\u2019s all I wanted to talk about for this blog entry. There were of course other changes and it\u2019s not possible to list them all but I think those are (mainly the first two) what affect users the most.<\/FONT><\/P>\n<P class=\"MsoNormal\">&nbsp;<\/P><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Certainly that\u2019s one of the most frequently asked questions I get (at the PDC too!). So since PDC already happened I can tell the rest of you about the new stuff happened in GC in CLR 2.0. The slides can be downloaded here. And I will be referring to some of the slides. I must [&hellip;]<\/p>\n","protected":false},"author":3542,"featured_media":58792,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[685],"tags":[3010,3011,108],"class_list":["post-23151","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-dotnet","tag-general","tag-maoniposts","tag-performance"],"acf":[],"blog_post_summary":"<p>Certainly that\u2019s one of the most frequently asked questions I get (at the PDC too!). So since PDC already happened I can tell the rest of you about the new stuff happened in GC in CLR 2.0. The slides can be downloaded here. And I will be referring to some of the slides. I must [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/23151","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/users\/3542"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/comments?post=23151"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/23151\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/media\/58792"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/media?parent=23151"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/categories?post=23151"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/tags?post=23151"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}