title: Limiting Java 8 Memory Consumption
body: <p>I'm running three Java 8 JVMs on a 64 bit Ubuntu VM which was built from a minimal install with nothing extra running other than the three JVMs. The VM itself has 2GB of memory and each JVM was limited by -Xmx512M which I assumed would be fine as there would be a couple of hundred MB spare.</p>
  
  <p>A few weeks ago, one crashed and the hs_err_pid dump showed:</p>
  
  <pre><code># There is insufficient memory for the Java Runtime Environment to continue.
  # Native memory allocation (mmap) failed to map 196608 bytes for committing reserved memory.
  # Possible reasons:
  #   The system is out of physical RAM or swap space
  #   In 32 bit mode, the process size limit was hit
  # Possible solutions:
  #   Reduce memory load on the system
  #   Increase physical memory or swap space
  #   Check if swap backing store is full
  #   Use 64 bit Java on a 64 bit OS
  #   Decrease Java heap size (-Xmx/-Xms)
  #   Decrease number of Java threads
  #   Decrease Java thread stack sizes (-Xss)
  #   Set larger code cache with -XX:ReservedCodeCacheSize=
  # This output file may be truncated or incomplete.
  </code></pre>
  
  <p>I restarted the JVM with a reduced heap size of 384MB and so far everything is fine. However when I currently look at the VM using the ps command and sort in descending RSS size I see</p>
  
  <pre><code>RSS %MEM    VSZ   PID CMD
  708768 35.4 2536124 29568 java -Xms64m -Xmx512m ...
  542776 27.1 2340996 12934 java -Xms64m -Xmx384m ...
  387336 19.3 2542336 6788 java -Xms64m -Xmx512m ...
  12128  0.6 288120  1239 /usr/lib/snapd/snapd
   4564  0.2  21476 27132 -bash
   3524  0.1   5724  1235 /sbin/iscsid
   3184  0.1  37928     1 /sbin/init
   3032  0.1  27772 28829 ps ax -o rss,pmem,vsz,pid,cmd --sort -rss
   3020  0.1 652988  1308 /usr/bin/lxcfs /var/lib/lxcfs/
   2936  0.1 274596  1237 /usr/lib/accountsservice/accounts-daemon
  ..
  ..
  </code></pre>
  
  <p>and the free command shows</p>
  
  <pre><code>              total        used        free      shared  buff/cache   available
  Mem:           1952        1657          80          20         213          41
  Swap:             0           0           0
  </code></pre>
  
  <p>Taking the first process as an example, there is an RSS size of 708768 KB even though the heap limit would be 524288 KB (512*1024).</p>
  
  <p>I am aware that extra memory is used over the JVM heap but the question is how can I control this to ensure I do not run out of memory again ? I am trying to set the heap size for each JVM as large as I can without crashing them. </p>
  
  <p>Or is there a good general guideline as to how to set JVM heap size in relation to overall memory availability ?</p>