Sizing Virtual Machines for JVM Workloads – Part 2

Looking at a Sizing Example

Figure 4, shows the most commonly encountered JVM and virtual machine size. This may be a fairly busy JVM with 100 to 250 concurrent threads (actual thread count varies as it depends on the nature of the workload), 4GB of heap, approximately 4.5GB for the JVM process, and 0.5GB for the guest OS. This results in a total recommended memory reservation for the virtual machine of 5GB with 2 vCPU and 1 JVM process.

Figure 4. Most Commonly Encountered Configuration


Figure 5 takes a closer look at the sizing example within the Java process, the memory layout, and for various sizes..

Figure 5. 5GB RAM Virtual Machine with One JVM Process and Two CPUs


The general sizing equation can be summarized as follows:


Let’s assume that, through load testing, a JVM max heap (-Xmx) of 4096m has been determined as necessary. Proceed to size as follows:

  • Set -Xmx4096m and set –Xms4096m.
  • Set –XX:MaxPermSize=256m. This value is a common number and depends on the memory footprint of the class-level information within your Java application code base..
  • The other segment of NumberOfConcurrentThreads*(-Xss) depends mostly on the NumberOfConcurrentThreads the JVM will process, and the –Xss value you have chosen. A common range of –Xss is 128k-192k. If, for example, NumberOfConcurrentThreads is 100, then 100*192k => 19200k (assuming you set –Xss to 192k).

Note: The stack -Xss is application dependent, i.e. if the stack is not sized correctly you will get a StackOverflow. The default value is sometimes quite large, but you can size it down to help save on memory consumption.

  • Assume the OS has a requirement of about 500m to run as per the OS spec.
  • Total JVM memory (java process memory) = 4096m (-Xmx) + 256m (–XX:MaxPermSize) + 100*192k (NumberOfConcurrentThreads*-Xss) + “other mem”.
  • Therefore, JVM memory is approximately 4096m+256m+19.2m + “other mem” = 4371m + “other mem”.
  • Typically “other mem” is not significant. However, it can be quite large if the application uses lots of NIO buffers and socket buffers. Otherwise, assuming about 5 percent of the total JVM process memory (i.e., 4 to 5 percent of 4371=> assume 217m), should be enough, although proper load testing should be used to verify.
  • This implies that JVM process memory is 4371m+217m=4588m
  • To determine the virtual machine memory, assume you are using Linux with only this single Java process and no other significant process running. The total configured memory for the virtual machine translates to: VM memory = 4588m + 500m = 5088m.
  • Finally, you should set the virtual machine memory as the memory reservation. You can choose to set the memory reservation as 5088m. However, over time you should monitor the active memory used by the virtual machine that houses this JVM process and adjust the memory reservation to that active memory value, which could be less than 5088m.

Stay tuned. In Part 3 we will conclude with an overview of the recently released book, Enterprise Java Applications Architecture on VMware.