{"id":566,"date":"2017-04-02T01:33:22","date_gmt":"2017-04-02T01:33:22","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/maoni\/?p=566"},"modified":"2021-09-30T10:20:59","modified_gmt":"2021-09-30T17:20:59","slug":"no-gcs-for-your-allocations","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/dotnet\/no-gcs-for-your-allocations\/","title":{"rendered":"No GCs for your allocations?"},"content":{"rendered":"<p>Several people mentioned Java\u2019s \u201cno GC\u201d GC proposal and asked if we can add such a thing. So I thought it deserves a blog post.<\/p>\n<p><strong>Short answer<\/strong> \u2013 we already have such a feature and that\u2019s called the NoGCRegion. The GC.TryStartNoGCRegion API allows you to tell us the amount of allocations you\u2019d like to do and when you stay within it, no GCs will be triggered. And you are free to revert back to doing normal GCs when you want to by calling GC.EndNoGCRegion. This is a better model than having a separate GC.<\/p>\n<p><strong>Long answer<\/strong> \u2013<\/p>\n<p>It\u2019s a better model because you have the flexibility to revert back to doing GCs when you need to. Would you rather have to spin up a whole new process just so that you can then do work that needs to do GCs (\u2018cause if you don\u2019t collect, well, your memory usage is just going to keep growing and unless you allocate really little you are going to run out pretty soon)?<\/p>\n<p>And yes, there\u2019s currently limitations on how much you can allocate with NoGCRegion. You can\u2019t allocate an arbitrary amount on SOH \u2013 I limited it to the SOH segment size just because we\u2019ve always had the same size for SOH segments so far. There\u2019s no theoretical limit that segments have to be the same size. It\u2019s a matter of doing the work to make sure we don\u2019t have places that accidently (artificially) enforce such a limit. There are other design options but I won&#8217;t get into the details here.<\/p>\n<p>So this means if you are using Server GC you are able to ask for a lot more memory on SOH because its SOH segment size is a lot larger. Currently (and this has been the case for a long time) the default seg size on 64-bit for Server GC is 4GB and we do cut that in half when you have &gt; 4 procs and again if you have &gt; 8 procs. So you have &gt; 8 procs it means the SOH segment size is 1GB each.<\/p>\n<p>On Desktop you have ways to make the SOH segment size larger \u2013<\/p>\n<p>use the <code>gcSegmentSize<\/code> app config or\nuse the <code>ICLRGCManager::SetGCStartupLimits<\/code><\/p>\n<p>For LOH as long as we can reserve and commit that much memory this will allow you to allocate \u2018cause LOH can already have totally different sized segments.<\/p>\n<p>We choose to make sure we can commit the amount of memory you ask for instead of randomly throwing you OOM because when you use such a feature you really should have a good idea how much you want to allocate. If you do have a scenario that says \u201cI just want to allocate till I get OOM and I don\u2019t care if I randomly get OOM\u201d please let me know &#8211; I\u2019d like to understand what the rationale is.<\/p>\n<p>I did have some bugs when I first checked this into 4.6.x (thanks Matt Warren for reporting). I\u2019ve made fixes in the current release. But I wanted to explain how it\u2019s supposed to work so you know what\u2019s a bug and what\u2019s a design limitation.<\/p>\n<p>And we also are still paying the write barrier cost while you are allocating in the NoGCRegion \u2013 I kept it that way because when you revert back to doing GCs you do need the info that the write barrier recorded if we don&#8217;t do anything special. However, if we so choose, we can just not have the write barrier for NoGCRegion and when we need to revert back to doing GCs we just promote everything that\u2019s still live to gen2 (would be reasonable to do as at this point you are very likely done with all the temporary stuff and what\u2019s left is justified to be in the old generation) and get the write barrier back in the picture again. I didn\u2019t do it this way because write barrier cost generally doesn\u2019t come up \u2013 not to say that it can\u2019t ever be a problem. It\u2019s just that we always need to prioritize the work based on how much it\u2019s needed.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Several people mentioned Java\u2019s \u201cno GC\u201d GC proposal and asked if we can add such a thing. So I thought it deserves a blog post. Short answer \u2013 we already have such a feature and that\u2019s called the NoGCRegion. The GC.TryStartNoGCRegion API allows you to tell us the amount of allocations you\u2019d like to do [&hellip;]<\/p>\n","protected":false},"author":3542,"featured_media":58792,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[685],"tags":[3011],"class_list":["post-566","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-dotnet","tag-maoniposts"],"acf":[],"blog_post_summary":"<p>Several people mentioned Java\u2019s \u201cno GC\u201d GC proposal and asked if we can add such a thing. So I thought it deserves a blog post. Short answer \u2013 we already have such a feature and that\u2019s called the NoGCRegion. The GC.TryStartNoGCRegion API allows you to tell us the amount of allocations you\u2019d like to do [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/566","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=566"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/566\/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=566"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/categories?post=566"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/tags?post=566"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}