JVM Options for Allocating Memory

JVM options to allocate memory - image of computer memory chip

Last week we mentioned the two most important factors affecting garbage collection performance. These are total available memory and the ratio of the heap allocated to the young generation.

This week we’ll look at some of the JVM runtime options to set memory sizes. This is as important as choosing the right garbage collector.

Remember that most garbage collectors have two generations: young and old. The young generation has three areas: Eden and two equal-sized survivor spaces. There is also a certain amount of virtual space in both generations. This is uncommitted heap space which will be used as the heap grows.

Total Heap Size

The most important setting is the total available memory. The maximum heap size is set with the -Xmx flag. The initial/starting size of the heap is set with the -Xms flag. The space for the entire heap is reserved when the JVM starts up.

It’s very important to always set the maximum heap size to less than the amount of physical memory. This minimises page faults and thrashing (copying memory contents to and from disk).

A rule of thumb is to start with -Xmx set at twice the size of the live set. The live set is the stable runtime size of the heap after garbage collections.

The -Xmx option is the same as the -XX:MaxHeapSize option.

If -Xms is smaller than -Xmx, then not all the reserved space is immediately committed to the VM. The uncommitted space is the virtual space. Both generations can grow to the limit of the virtual space as needed, based on the ratio between them.

Setting -Xms and -Xmx to the same value makes it easier to predict the application footprint (total memory used). However, this prevents the JVM growing and shrinking the heap to meet any throughout goals we may have set. If we choose incorrect/poor values, the JVM can’t adjust the heap size up or down.

Young Generation Size

The second most important setting is the ratio of the heap dedicated to the young generation.

The parameter –XX:NewRatio specifies the ratio of the young to the old generation.

For example, setting -XX:NewRatio=3 means that the ratio between the young and old generation is 1:3. In other words, the combined size of Eden and the survivor spaces will be one quarter of the total heap size. We can only use whole numbers when setting this ratio.

-Xmnsize sets both the initial and maximum size of the heap for the young generation.

We can use -XX:NewSize to set the initial size and -XX:MaxNewSize to set the maximum size separately. These options are useful for fine-tuning the young generation.

The bigger the young generation, the less often minor collections occur. For a fixed heap size, a larger young generation forces a smaller old generation. This increases the number of major collections. The optimal ratio will depend on the lifetimes of the objects created by the application.

Survivor Space Size

We can use the -XX:SurvivorRatio flag to set the survivor space sizes. This isn’t usually necessary for performance tuning.

The -XX:SurvivorRatio parameter changes the size of the survivor spaces. For example, -XX:SurvivorRatio=6 sets the ratio between Eden and a survivor space to 1:6. Each survivor space will be one-sixth of the size of Eden.

If survivor spaces are too small, then the copying collection overflows directly into the old generation. If survivor spaces are too large, then they are almost empty. At each garbage collection, the virtual machine chooses a threshold number. This is the number of times an object can be copied before it’s old. The threshold is chosen to keep the survivor spaces half full.


The performance of a garbage collector is dependent on the size of the heap, the amount of live data, and the number and speed of available processors. The following are guidelines for heap sizes for server applications:

  • Allocate as much memory as possible to the JVM. The default size is often too small. Usually more heap memory is better for low pause collections. However, with huge heap sizes the GC pauses can become problematic.

  • Decide on the maximum heap size to allocate to the JVM. Then check the performance with different young generation sizes to find the best setting.

  • Increase the heap memory as the number of processors increases. This allows the use of a parallel garbage collector.

  • If the total heap size is fixed, then increasing the young generation size reduces the old generation size. Keep the old generation large enough to hold all the live data, plus some extra space (10% to 20% or more).

  • Bearing the previous constraints on the old generation in mind:

    • Allocate plenty of memory to the young generation.

    • Increase the young generation size as the number of processors increases.

If the current garbage collector doesn’t give us the performance we need, we should first adjust the heap and generation sizes to meet the goals. If performance is still too slow, then we should try a different collector. For example, we can use the concurrent collector to reduce pause-times. We can use the parallel collector to increase throughput on multiprocessor hardware.

Extra Reading

For more than you’ll probably ever need to know about garbage collection, see this [Java 18 article]
(https://docs.oracle.com/en/java/javase/18/gctuning/index.html) on the Oracle website.

This is the Java 11 version of the previous article, while this is the Java 8 version.

This is an excellent article by Jack Shirazi. Be sure to watch the associated Youtube video where he explains how to choose a garbage collector and tune it.

Until next week, stay safe and keep on learning! And don’t forget to share your thoughts and comments on this post.

Leave a Comment

Your email address will not be published. Required fields are marked *

Code like a Java Guru!

Thank You

We're Excited!

Thank you for completing the form. We're excited that you have chosen to contact us about training. We will process the information as soon as we can, and we will do our best to contact you within 1 working day. (Please note that our offices are closed over weekends and public holidays.)

Don't Worry

Our privacy policy ensures your data is safe: Incus Data does not sell or otherwise distribute email addresses. We will not divulge your personal information to anyone unless specifically authorised by you.

If you need any further information, please contact us on tel: (27) 12-666-2020 or email info@incusdata.com

How can we help you?

Let us contact you about your training requirements. Just fill in a few details, and we’ll get right back to you.

Your Java tip is on its way!

Check that incusdata.com is an approved sender, so that your Java tips don’t land up in the spam folder.

Our privacy policy means your data is safe. You can unsubscribe from these tips at any time.