{"id":1775,"date":"2010-12-13T13:54:41","date_gmt":"2010-12-13T17:54:41","guid":{"rendered":"http:\/\/www.webperformanceinc.com\/load_testing\/blog\/?p=1775"},"modified":"2011-01-26T10:21:35","modified_gmt":"2011-01-26T14:21:35","slug":"garbage-collector-performance-under-load","status":"publish","type":"post","link":"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/2010\/12\/garbage-collector-performance-under-load\/","title":{"rendered":"Garbage Collector Performance under Load"},"content":{"rendered":"<p>The overwhelming majority of dynamic internet-facing applications are built on garbage collected runtimes such as Java and .NET.\u00a0 Garbage collection is popular because it promotes rapid application development.\u00a0 On the other hand, whenever a system is demonstrating unexpectedly poor performance, the garbage collector invariably surfaces as a possible suspect.\u00a0 Our advanced server analysis module even hooks into garbage collection performance monitoring on the .NET platform.<\/p>\n<p>The reality, however, is that modern garbage collectors are very good.<\/p>\n<p><strong>Fact:<\/strong> Our company has been in business since 1999.\u00a0 In this time, no one can recall ever encountering a system with a performance problem that could primarily be attributed to poor garbage collector performance in the absense of any other resource constraint.<\/p>\n<p>In general, there are two variables that impact the overhead of a modern, precise, multi-generational garbage collector: pause duration and collection frequency.<\/p>\n<p><strong>As a rough rule, garbage collector pause durations are proportional to the number of live objects in the heap.<\/strong> If, at the beginning of a collection event, there are 1000 objects, and ten are live, then the GC merely needs to traverse the ten live objects and copy their handles into a new allocation table.\u00a0 If all 1000 objects are live, then the GC needs to traverse all of them and frees no memory for the effort.<\/p>\n<p><strong>Collection frequency is proportional to the rate at which objects are created and inversely proportional to the amount of free memory.<\/strong> This makes intuitive sense: if we have infinite memory, then we never need to perform garbage collection.\u00a0 If we have nearly zero memory, then the garbage collector will run on every allocation request.<\/p>\n<p>If we double the amount of free memory, we can create twice as many objects before we need to run a collection &#8212; but the collection does not necessarily take any longer to complete.<\/p>\n<p><strong>High garbage collection overhead is, almost without exception, a symptom of insufficient free memory.<\/strong> Rapidly creating objects, in and of itself, will not necessarily cause significant garbage collection overhead &#8212; this is the use case for which modern GCs are optimized.<\/p>\n<p><strong>Garbage collection is performed by the CPU.<\/strong> Web infrastructure that is not already saturated can &#8220;catch up&#8221; after a brief delaying event such as\u00a0 a garbage collection in a way that is not discernible to casual end-users.\u00a0 If a web application is not showing 100% utilization on at least one processor core, then its performance is not actually being impacted by the garbage collector.<\/p>\n<p><strong>Garbage collection is sometimes serial.<\/strong> This is in principle a problem for newer many-core web servers.\u00a0 Data structures that don&#8217;t lend themselves to parallelism can&#8217;t be garbage collected in parallel, either.\u00a0 The particular GC algorithm you use may have a significant impact on many-core systems.<\/p>\n<p><strong>Conclusion:<\/strong> The takeaway here is that garbage collection fails in a small number of fairly specific ways, and that poor garbage collection performance is usually symptomatic of a hardware resource constraint.\u00a0 We should be careful not to assume that performance problems can be explained away by the ordinary function of the garbage collector.<\/p>\n<p>&#8212; Lane, engineer at Web Performance.<\/p>\n<p>Further reading:<\/p>\n<p><a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ee851764.aspx\">http:\/\/msdn.microsoft.com\/en-us\/library\/ee851764.aspx<\/a><\/p>\n<p><a href=\"http:\/\/developers.sun.com\/mobility\/midp\/articles\/garbage\/\">http:\/\/developers.sun.com\/mobility\/midp\/articles\/garbage\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>The overwhelming majority of dynamic internet-facing applications are built on garbage collected runtimes such as Java and .NET.\u00a0 Garbage collection is popular because it promotes rapid application development.\u00a0 On the other hand, whenever a system is demonstrating unexpectedly poor performance, the garbage collector invariably surfaces as a possible suspect.\u00a0 Our advanced server analysis module even hooks into garbage collection performance monitoring on the .NET platform.<br \/>\nThe reality, however, is that modern garbage collectors are very good.<br \/>\nFact: Our company has been in business since 1999.\u00a0 In this time, no one can recall ever encountering a system with a performance problem that could &hellip; <a href=\"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/2010\/12\/garbage-collector-performance-under-load\/\">Continue reading &raquo;<\/a><\/p>\n","protected":false},"author":53,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[35,4],"tags":[110,237],"class_list":["post-1775","post","type-post","status-publish","format-standard","hentry","category-aspnet","category-javaj2ee","tag-garbage-collection","tag-load-testing"],"_links":{"self":[{"href":"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-json\/wp\/v2\/posts\/1775","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-json\/wp\/v2\/users\/53"}],"replies":[{"embeddable":true,"href":"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-json\/wp\/v2\/comments?post=1775"}],"version-history":[{"count":16,"href":"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-json\/wp\/v2\/posts\/1775\/revisions"}],"predecessor-version":[{"id":1861,"href":"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-json\/wp\/v2\/posts\/1775\/revisions\/1861"}],"wp:attachment":[{"href":"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-json\/wp\/v2\/media?parent=1775"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-json\/wp\/v2\/categories?post=1775"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-json\/wp\/v2\/tags?post=1775"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}