Create an account


Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[Oracle Blog] Java Heap Sizing in a Container: Quickly and Easily

#1
Java Heap Sizing in a Container: Quickly and Easily

<p>In the previous blog, We have seen that Java has made improvements to identify the memory based on a running environment i.e. either a physical machine or a Container (docker). The initial problem with java was that It wasn't able to figure out that it was running in a container and It used to capture the memory for whole hardware where the container was running. (Please see -&nbsp;<span><a href="https://blogs.oracle.com/java/java-on-container-like-a-pro">ttps://blogs.oracle.com/java/java-on-container-like-a-pro</a>)</span></p>

<p><span>Now a Java Program&nbsp;running in a container is able to identify the cgroup limit and assign the memory (heap) according to that, (If we do not specify the min and max heap size, which we used to define earlier). So we can run our java program in a container and utilize hardware memory properly, but can we very sure that Java program is using heap size according to cgroup definition?</span></p>

<p>We have a solution to this problem as&nbsp;<span style="font-size:11.0pt"><span style="line-height:107%"><span style="font-family:&quot;Calibri&quot;,sans-serif">XshowSettings:category.&nbsp;</span></span></span>This is a handy HotSpot JVM flag (option for the Java launcher java) is the -XshowSettings option. This option is described in the Oracle Java launcher description page as follows:</p>

<p><em><strong>-XshowSettings:category</strong><br />
Shows settings and continues. Possible category arguments for this option include the following:</em></p>

<p><em><strong>all</strong><br />
Shows all categories of settings. This is the default value.</em></p>

<p><em><strong>locale</strong><br />
Shows settings related to locale.</em></p>

<p><em><strong>properties</strong><br />
Shows settings related to system properties.</em></p>

<p><em><strong>vm</strong><br />
Shows the settings of the JVM.</em></p>

<p><em>[These types of flags described in the Java tech note -&nbsp;<span>as&nbsp;</span><a href="https://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html">https://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html</a>&nbsp;]</em></p>

<p>The showSettings flag provides lots of details about the program running in that JVM, however, our interest is to find out the memory utilization so we will stick to the argument as -&gt;&nbsp;<span style="font-size:11.0pt"><span style="line-height:107%"><span style="font-family:&quot;Calibri&quot;,sans-serif">-XshowSettings:vm -version</span></span></span></p>

<p>Let's verify this by running a simple container program without specifying the cgroup flag (which informs java that the program is running in a Java container)</p>

<p style="margin-bottom:11px"><span style="font-size:11pt"><span style="line-height:107%"><span style="font-family:Calibri,sans-serif"><i>(I set a container memory of 100MB and my JVM sets a max heap of 3.24G)</i></span></span></span></p>

<p style="margin-left:48px; margin-bottom:11px"><span style="font-size:11pt"><span style="line-height:107%"><span style="font-family:Calibri,sans-serif">[root&nbsp;java-8]# docker run -m 100MB oracle-server-jre java -XshowSettings:vm -version</span></span></span></p>

<p style="margin-left:48px; margin-bottom:11px"><span style="font-size:11pt"><span style="line-height:107%"><span style="font-family:Calibri,sans-serif">VM settings:</span></span></span></p>

<p style="margin-left:48px; margin-bottom:11px"><span style="font-size:11pt"><span style="line-height:107%"><span style="font-family:Calibri,sans-serif">&nbsp;&nbsp;&nbsp; Max. Heap Size (Estimated): 3.24G</span></span></span></p>

<p style="margin-left:48px; margin-bottom:11px"><span style="font-size:11pt"><span style="line-height:107%"><span style="font-family:Calibri,sans-serif">&nbsp;&nbsp;&nbsp; Ergonomics Machine Class: server</span></span></span></p>

<p style="margin-left:48px; margin-bottom:11px"><span style="font-size:11pt"><span style="line-height:107%"><span style="font-family:Calibri,sans-serif">&nbsp;&nbsp;&nbsp; Using VM: Java HotSpot™ 64-Bit Server VM</span></span></span></p>

<p style="margin-left:48px; margin-bottom:11px">&nbsp;</p>

<p style="margin-left:48px; margin-bottom:11px"><span style="font-size:11pt"><span style="line-height:107%"><span style="font-family:Calibri,sans-serif">java version &quot;1.8.0_181&quot;</span></span></span></p>

<p style="margin-left:48px; margin-bottom:11px"><span style="font-size:11pt"><span style="line-height:107%"><span style="font-family:Calibri,sans-serif">Java™ SE Runtime Environment (build 1.8.0_181-b13)</span></span></span></p>

<p style="margin-left:48px; margin-bottom:11px"><span style="font-size:11pt"><span style="line-height:107%"><span style="font-family:Calibri,sans-serif">Java HotSpot™ 64-Bit Server VM (build 25.181-b13, mixed mode)</span></span></span></p>

<p style="margin-bottom:11px">&nbsp;</p>

<p style="margin-bottom:11px"><strong>We can clearly see that Java Heap is capturing the heap available to the hardware however the docker size was specified to 100 mb only, Now let's tell Java that the program is running inside the container and see the results.</strong></p>

<p><em>With java version 1.8.0_181 (including unlock experimental version and Cgroup limit with a specification of memory 1GB MB) with only jdk Docker&nbsp;</em></p>

<p><em>[root]# docker run -m 1GB oracle-server-jre java -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -XshowSettings:vm -version<br />
VM settings:<br />
&nbsp; &nbsp; Max. Heap Size (Estimated): 228.00M<br />
&nbsp; &nbsp; Ergonomics Machine Class: server<br />
&nbsp; &nbsp; Using VM: Java HotSpot™ 64-Bit Server VM</em></p>

<p><em>java version &quot;1.8.0_181&quot;<br />
Java™ SE Runtime Environment (build 1.8.0_181-b13)<br />
Java HotSpot™ 64-Bit Server VM (build 25.181-b13, mixed mode)</em><br />
&nbsp;</p>

<p style="margin-bottom:11px"><strong>The JVM was able to detect the container has only 1GB and set the max heap to 228M, which is almost 1/4th of the total available size.</strong></p>

<p style="margin-bottom:11px">We can see that the Java Heap is set to 1/4th of the docker size and rest of the 3/4th memory is utilized by docker, but what if our container doesn't require 3/4 memory,&nbsp;&nbsp;</p>

<p style="margin-bottom:11px">If the container or the program configuration doesn't need that much of memory then this is not the correct utilization of memory. The ratio between Java heap and Container size is defined inside JVM code, so the question is - can we configure this ratio??&nbsp;</p>

<p style="margin-bottom:11px">Yes, Java did a very good thing by providing another option to change the ratio of container memory and java heap size. Java introduced another flag as&nbsp;<span style="font-size:11.0pt"><span style="line-height:107%"><span style="font-family:&quot;Calibri&quot;,sans-serif">MaxRAMFraction</span></span></span>&nbsp;( the default value to this flag is 4, so heap size takes 1/4th of container size and we can change it by defining it explicitly)</p>

<p>we have defined RAM fraction =2, Which settles heap size on almost 50% of the total.<br />
[root]# docker run -m 1GB oracle-server-jre java -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -XX:MaxRAMFraction=2 -XshowSettings:vm -version<br />
VM settings:&nbsp;&nbsp; &nbsp;<br />
&nbsp; &nbsp; Max. Heap Size (Estimated): 455.50M<br />
&nbsp; &nbsp; Ergonomics Machine Class: server<br />
&nbsp; &nbsp; Using VM: Java HotSpot™ 64-Bit Server VM</p>

<p>java version &quot;1.8.0_181&quot;<br />
Java™ SE Runtime Environment (build 1.8.0_181-b13)<br />
Java HotSpot™ 64-Bit Server VM (build 25.181-b13, mixed mode)</p>

<p><strong>The heap size reaches approximately to 50% of the total container size.</strong></p>

<p style="margin-bottom:11px">Now we can change the ratio as well according to our Java program comfort level, but this leads to another thought that is is safe to run a container,&nbsp;if we define this&nbsp;ratio to 1? (however JVM won't capture whole container memory and It leaves some memory to run some other container programs like container debug shell (docker exec) and diagnostics, OS processes, etc. If the program or container needs more memory under load then it will kill the container, so I feel defining the least ratio-XX:MaxRAMFraction=2&nbsp;seems safe(ish), if we want to customize the default JVM ratio which seems to be&nbsp;the safest ratio.</p>



https://blogs.oracle.com/java/java-heap-...and-easily
Reply



Forum Jump:


Users browsing this thread:
1 Guest(s)

Forum software by © MyBB Theme © iAndrew 2016