{"id":508,"date":"2016-06-29T11:26:38","date_gmt":"2016-06-29T11:26:38","guid":{"rendered":"http:\/\/smartfoxserver.com\/blog\/?p=508"},"modified":"2016-06-29T11:27:54","modified_gmt":"2016-06-29T11:27:54","slug":"understanding-jvmsmartfoxserver-memory-usage","status":"publish","type":"post","link":"https:\/\/smartfoxserver.com\/blog\/understanding-jvmsmartfoxserver-memory-usage\/","title":{"rendered":"Understanding JVM\/SmartFoxServer memory usage"},"content":{"rendered":"<p>In this article we&#8217;re going to address yet another oft-asked question regarding how SmartFoxServer uses memory and how to read the graph in the AdminTool&#8217;s Dashboard.<!--more--><\/p>\n<p>When we open the Dashboard in SFS2X&#8217;s AdminTool we find, among other things, a diagram of the heap memory used to hold the application&#8217;s object instances.<\/p>\n<p><img loading=\"lazy\" class=\" size-full wp-image-509 aligncenter\" src=\"http:\/\/smartfoxserver.com\/blog\/wp-content\/uploads\/2016\/06\/memory-diag1.png\" alt=\"memory-diag1\" width=\"930\" height=\"259\" srcset=\"https:\/\/smartfoxserver.com\/blog\/wp-content\/uploads\/2016\/06\/memory-diag1.png 930w, https:\/\/smartfoxserver.com\/blog\/wp-content\/uploads\/2016\/06\/memory-diag1-300x84.png 300w, https:\/\/smartfoxserver.com\/blog\/wp-content\/uploads\/2016\/06\/memory-diag1-624x174.png 624w\" sizes=\"(max-width: 930px) 100vw, 930px\" \/><\/p>\n<p>At a first glance the graph\u00a0shows two basic parameters, the amount of used memory (blue) and the allocated memory (cyan), but there&#8217;s more. At the top of the graph there&#8217;s a &#8220;Max&#8221; value of approximately 239 MBytes, which represents the top\u00a0limit that SmartFoxServer can\u00a0allocate, if needed. If our application required, for example, to allocate 300 MBytes of data it would incur in\u00a0an OutOfMemory error, \u00a0which is an unrecoverable exception and it would fail.<\/p>\n<p>In order to be able to solve this issue we need to add specific boot-time settings to make sure the JVM starts up with enough resources.<\/p>\n<p>Before we discuss it, let&#8217;s recap the three main parameters of JVM heap memory:<\/p>\n<ul>\n<li><strong>Used heap<\/strong>: the amount of memory actually used by objects<\/li>\n<li><strong>Allocated\u00a0heap<\/strong>: the amount of heap memory currently allocated<\/li>\n<li><strong>Max heap<\/strong>: the maximum amount that the <strong>Allocated<\/strong> value can reach, if and when necessary<\/li>\n<\/ul>\n<h2>\u00bb JVM startup settings<\/h2>\n<p>When the\u00a0Java Virtual Machine boots up it\u00a0auto-determines a reasonable amount of memory to use based on the system&#8217;s configuration. On a Linux system with 2\u00a0GBytes of system RAM the JVM\u00a0will boot\u00a0with ~460MB of max memory, which is usually more than enough\u00a0for many SmartFoxServer use cases. On a 16GB server machine it will boot up with a max heap size of approximately\u00a03.5GBytes.<\/p>\n<p>Generally speaking SmartFoxServer 2X uses very little memory, it can even run with only 32 Mbytes of RAM and\u00a0it doesn&#8217;t need manual memory settings even when the traffic is in the thousands of CCU. However there can be situations in which more RAM is required especially when custom server side code is used, or very high traffic needs to be sustained.<\/p>\n<p>There are two main JVM parameters for setting the heap size at startup:<\/p>\n<p><strong>-Xms<\/strong>: specifies the minimum heap size in MB or GB<br \/>\n<strong>-Xmx<\/strong>: specifies the maximum heap size in MB or GB.<\/p>\n<p>For example this combo: <strong>-Xms512M -Xmx2G<\/strong>, indicates that the JVM will start up with 512 MBytes of allocated heap and a maximum size of 2 GBytes.<\/p>\n<p>These settings can be added via the SmartFoxServer&#8217;s <strong>AdminTool<\/strong> &gt; <strong>Server Configurator<\/strong> &gt; <strong>JVM Settings<\/strong>. You can read more about adding custom JVM settings in our <a title=\"Custom JVM Settings\" href=\"http:\/\/docs2x.smartfoxserver.com\/GettingStarted\/admintool-ServerConfigurator\" target=\"_blank\">documentation<\/a>.<\/p>\n<h2>\u00bb\u00a0Common questions<\/h2>\n<p>On multiple occasions we have been contacted by developers that were monitoring their server and were worried that heap\u00a0memory seemed to\u00a0running out quickly, such as in this screenshot:<\/p>\n<p><a href=\"http:\/\/smartfoxserver.com\/blog\/wp-content\/uploads\/2016\/06\/memory-diag2.png\"><img loading=\"lazy\" class=\" size-full wp-image-512 aligncenter\" src=\"http:\/\/smartfoxserver.com\/blog\/wp-content\/uploads\/2016\/06\/memory-diag2.png\" alt=\"memory-diag2\" width=\"1900\" height=\"566\" srcset=\"https:\/\/smartfoxserver.com\/blog\/wp-content\/uploads\/2016\/06\/memory-diag2.png 1900w, https:\/\/smartfoxserver.com\/blog\/wp-content\/uploads\/2016\/06\/memory-diag2-300x89.png 300w, https:\/\/smartfoxserver.com\/blog\/wp-content\/uploads\/2016\/06\/memory-diag2-1024x305.png 1024w, https:\/\/smartfoxserver.com\/blog\/wp-content\/uploads\/2016\/06\/memory-diag2-624x186.png 624w\" sizes=\"(max-width: 1900px) 100vw, 1900px\" \/><\/a><\/p>\n<p>At a first glance it looks like the used heap is reaching the limit, but&#8230; if you just hold on\u00a0for a moment and look what happens a few minutes later&#8230;<\/p>\n<p><a href=\"http:\/\/smartfoxserver.com\/blog\/wp-content\/uploads\/2016\/06\/memory-diag3.png\"><img loading=\"lazy\" class=\" size-full wp-image-513 aligncenter\" src=\"http:\/\/smartfoxserver.com\/blog\/wp-content\/uploads\/2016\/06\/memory-diag3.png\" alt=\"memory-diag3\" width=\"1902\" height=\"560\" srcset=\"https:\/\/smartfoxserver.com\/blog\/wp-content\/uploads\/2016\/06\/memory-diag3.png 1902w, https:\/\/smartfoxserver.com\/blog\/wp-content\/uploads\/2016\/06\/memory-diag3-300x88.png 300w, https:\/\/smartfoxserver.com\/blog\/wp-content\/uploads\/2016\/06\/memory-diag3-1024x301.png 1024w, https:\/\/smartfoxserver.com\/blog\/wp-content\/uploads\/2016\/06\/memory-diag3-624x184.png 624w\" sizes=\"(max-width: 1902px) 100vw, 1902px\" \/><\/a><\/p>\n<p>The memory management inside the JVM is very smart but\u00a0works in an indeterministic way.\u00a0The used memory was growing fast in the first diagram because a number of unused objects were still held in the heap. In the 2nd screenshot we see the garbage collector (GC) cleaning up the used memory, while at the same time the allocated heap\u00a0is pushed up a bit, from ~95 MBytes to ~140 MBytes, which is still way below the limit of 466 MBytes, shown on top of the graph.<\/p>\n<p>The moral of the story is that the JVM memory management\u00a0is difficult to predict for an external onlooker and usually there is no need to worry if the used and allocated memory seem to collide.<\/p>\n<h2>\u00bb\u00a0When to intervene<\/h2>\n<p>At this point one may be asking: if memory management is indeterministic and the behavior of the GC is unpredictable how do we know when we its time to fine tune the JVM&#8217;s memory?<\/p>\n<p>Typically the red flag\u00a0is triggered by the allocated memory being pushed to the limit (allocated heap size == max heap size) and by frequent and small peaks and troughs of the used memory, indicating that the GC is very busy.<\/p>\n<p>Here&#8217;s an example of a diagram that suggests manual intervention\u00a0is\u00a0in order:<\/p>\n<p><a href=\"http:\/\/smartfoxserver.com\/blog\/wp-content\/uploads\/2016\/06\/memory-diag4.png\"><img loading=\"lazy\" class=\" size-full wp-image-515 aligncenter\" src=\"http:\/\/smartfoxserver.com\/blog\/wp-content\/uploads\/2016\/06\/memory-diag4.png\" alt=\"memory-diag4\" width=\"928\" height=\"260\" srcset=\"https:\/\/smartfoxserver.com\/blog\/wp-content\/uploads\/2016\/06\/memory-diag4.png 928w, https:\/\/smartfoxserver.com\/blog\/wp-content\/uploads\/2016\/06\/memory-diag4-300x84.png 300w, https:\/\/smartfoxserver.com\/blog\/wp-content\/uploads\/2016\/06\/memory-diag4-624x175.png 624w\" sizes=\"(max-width: 928px) 100vw, 928px\" \/><\/a>We forced the server to run with only ~40MB of RAM, this in turn provides a max size of 37 MBytes for the\u00a0heap. We\u00a0can see that the allocated memory is already maxed out and the\u00a0many\u00a0peaks and troughs indicate very frequent\u00a0garbage collections. In only 3 minutes of activity the GC was triggered\u00a0more than\u00a020 times.<\/p>\n<p>This is definitely a case where improved heaps settings will help. If we run the same test with these JVM settings: -Xms512M -Xmx1G<\/p>\n<p><a href=\"http:\/\/smartfoxserver.com\/blog\/wp-content\/uploads\/2016\/06\/memory-diag5.png\"><img loading=\"lazy\" class=\" size-full wp-image-516 aligncenter\" src=\"http:\/\/smartfoxserver.com\/blog\/wp-content\/uploads\/2016\/06\/memory-diag5.png\" alt=\"memory-diag5\" width=\"932\" height=\"268\" srcset=\"https:\/\/smartfoxserver.com\/blog\/wp-content\/uploads\/2016\/06\/memory-diag5.png 932w, https:\/\/smartfoxserver.com\/blog\/wp-content\/uploads\/2016\/06\/memory-diag5-300x86.png 300w, https:\/\/smartfoxserver.com\/blog\/wp-content\/uploads\/2016\/06\/memory-diag5-624x179.png 624w\" sizes=\"(max-width: 932px) 100vw, 932px\" \/><\/a><\/p>\n<p>we can see an entirely different picture, \u00a0with plenty of free heap in the allocated range and a much less frequent\u00a0GC activity in the same time range.<\/p>\n<h2>\u00bb\u00a0Too much memory can also be bad<\/h2>\n<p>Before\u00a0we wrap this article up\u00a0we would also recommend not to get too carried away with\u00a0extra large amounts of memory as well. We have seen setups where the JVM was\u00a0assigned 12,16 or even more GBytes of RAM and unless there&#8217;s a very specific reason for this, we don&#8217;t recommend it.<\/p>\n<p>Throwing king size amounts of heap memory at the JVM, with the purpose of minimizing the GC activity,\u00a0is counterproductive leading to\u00a0very long GC pauses that\u00a0could grind\u00a0the server to a halt\u00a0and make it\u00a0unresponsive for too long.<\/p>\n<p>This means that all incoming traffic needs to be buffered and when the GC cycle ends there will be huge spikes of load resulting in more network spikes etc&#8230; Not the best behavior you would want from your server.<\/p>\n<p>If you really need a very large heap size (&gt; 8 GBytes) we recommend to also fine tune the garbage collector, maybe employing a concurrent\u00a0GC to avoid stopping the server&#8217;s active\u00a0threads.<\/p>\n<h2>\u00bb Learn more<\/h2>\n<p>Here are a few relevant articles if you&#8217;re interested to learn more about fine tuning the JVM<\/p>\n<ul>\n<li><a href=\"http:\/\/docs.oracle.com\/cd\/E15523_01\/web.1111\/e13814\/jvm_tuning.htm#PERFM150\" target=\"_blank\">Oracle:\u00a0Tuning Java Virtual Machines<\/a><\/li>\n<li><a href=\"http:\/\/stackoverflow.com\/questions\/11021434\/does-java-heap-memory-change-based-on-ram\" target=\"_blank\">Stackoverflow:\u00a0Does Java heap memory change based on RAM?<\/a><\/li>\n<li><a href=\"http:\/\/howtodoinjava.com\/core-java\/garbage-collection\/jvm-memory-model-structure-and-components\/\" target=\"_blank\">JVM Memory model<\/a><\/li>\n<li><a href=\"http:\/\/www.cubrid.org\/blog\/dev-platform\/how-to-tune-java-garbage-collection\/\" target=\"_blank\">Overview of Garbage Collection tuning<\/a><\/li>\n<li><a href=\"http:\/\/www.oracle.com\/technetwork\/java\/gc-tuning-5-138395.html\" target=\"_blank\">Oracle: Tuning Garbage Collection<\/a><\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this article we&#8217;re going to address yet another oft-asked question regarding how SmartFoxServer uses memory and how to read the graph in the AdminTool&#8217;s Dashboard.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[23],"tags":[70,69,68,40,34,7,71],"_links":{"self":[{"href":"https:\/\/smartfoxserver.com\/blog\/wp-json\/wp\/v2\/posts\/508"}],"collection":[{"href":"https:\/\/smartfoxserver.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/smartfoxserver.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/smartfoxserver.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/smartfoxserver.com\/blog\/wp-json\/wp\/v2\/comments?post=508"}],"version-history":[{"count":7,"href":"https:\/\/smartfoxserver.com\/blog\/wp-json\/wp\/v2\/posts\/508\/revisions"}],"predecessor-version":[{"id":520,"href":"https:\/\/smartfoxserver.com\/blog\/wp-json\/wp\/v2\/posts\/508\/revisions\/520"}],"wp:attachment":[{"href":"https:\/\/smartfoxserver.com\/blog\/wp-json\/wp\/v2\/media?parent=508"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/smartfoxserver.com\/blog\/wp-json\/wp\/v2\/categories?post=508"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/smartfoxserver.com\/blog\/wp-json\/wp\/v2\/tags?post=508"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}