Profile Image
vishnupriya

What is JVM startup parameter: -XX:ObjectAlignmentInBytes?

What is JVM startup parameter: -XX:ObjectAlignmentInBytes? Have you used this JVM arguement before? What are the pros & cons of using this Java argument? Can you share your perspective/experience in using this JVM argument?

  • jvmargument

  • xx-objectalignmentinbytes

  • x-objectalignmentinbytes

  • JVM startup parameter

Please Sign In or to post your comment or answer

Profile Image

Pavel Khodakovsky

Usage:


Set a default object alignment in bytes. Its syntax is: -XX:ObjectAlignmentInBytes=value, where value is a number that is superior than 8, is a power of 2 and within the range of 8 and 256.

 

Since:

 

Starting from JDK 6.

 

Examples:

 

To set an object alignment of 32 bytes:

 

java -XX:ObjectAlignmentInBytes=32 MainClass

 

Description:

 

Garbage Collector is a way of the JVM to clean the memory and makes the java memory more efficient. It tracks (Mark step) and removes (sweep step) every unused object available in the JVM heap space. An object is considered unused when it’s referenced by null, assigned to another reference or by anonymous object …. There are 5 type of GC implementations:

 

  • Serial Garbage Collector
  • Parallel Garbage Collector
  • CMS Garbage Collector
  • G1 Garbage Collector
  • Z Garbage Collector

Young Generation is a place where all new objects start out and aged. It’s divided into two spaces:

  • Eden Space: New object initiated with the keyword “new” are allocated in this memory space.
  • Survivor Space: When the Eden space is filled. A minor garbage collection event occurs. Objects that are referenced are marked and some are not. The ones which are marked will move to Survivor Space S0 and the one unmarked are removed by GC. When The space S0 filled, the cycle repeat itself but instead of moving them to S0, they will be moved to Survivor Space S1.

Old Generation is a place where objects that lived for a long time lie. If an object reaches an age threshold after surviving multiple GC events in the Young Generation, the object gets moved to the Old Generation.

 

In the heap, a 32-bit object reference (pointer) occupies 4 bytes, while a 64-bit object reference occupies 8 bytes. That is, a 64-bit object reference is twice the size of a 32-bit object. While the 64-bit JVM supports larger heaps, it brings performance problems due to larger object references:

 

  • Increased GC overhead: 64-bit object references need to occupy more heap space, leaving less space for other data, thus speeding up the occurrence of GC and performing GC more frequently.
  • Reduce the CPU cache hit rate: The 64-bit object reference increases, and the CPU can cache fewer oops, thereby reducing the efficiency of the CPU cache.

 

To be able to maintain 32-bit performance, OOP must remain 32-bit. So, how to use 32-bit OOP to reference larger heap memory? The answer is - Compressed Pointers (called sometimes Compressed Ordinary Object Pointer OOP).

 

When the flag “-XX:-UseCompressedOops” is enabled, the objects that will be compressed:

 

  • Property pointers (static member variables) for each Class
  • property pointer for each object
  • Each element pointer of a plain object array

 

The 64-bit address is divided into the base address + offset of the heap. When the heap memory is less than 32GB, during the compression process, the offset/8 is saved to the 32-bit address. After decompression, the 32-bit address is enlarged by 8 times, so the condition for enabling Compressed Pointers is that the heap memory should be within 4GB*8=32GB.

 

Compressed Pointers allows JVMs running on 64-bit platforms to avoid the cost of Heap capacity loss due to wider addressing. However, it is implemented by embedding compression and decompression instructions in the machine code, which may add additional overhead to the JVM.

 

This is how Compressed Pointers work. If the configured maximum heap memory exceeds 32 GB (when the JVM is 8-byte aligned), then the compressed pointer will fail. However, this 32 GB is related to the byte alignment size, which is the “-XX:ObjectAlignmentInBytes” configured size (the default is 8 bytes, that is, Java defaults to 8 bytes alignment). The flag “-XX:ObjectAlignmentInBytes” It can be set to an integer multiple of 8, up to 128. That is, if the configuration “-XX:ObjectAlignmentInBytes” is 24, then the configuration maximum heap memory exceeds 96 GB and the compressed pointer will be invalid.

 

We can test this with the following code:

First of all, we will run this code snippet with this arguments: “-Xmx16g -XX:ObjectAlignmentInBytes=8”

 

It can be seen that the type word size is 4 bytes 0x00c00c80, and the compressed pointer takes effect.

 

For the next step, we will use 32Gb for the maximum Heap Space and run it again “-Xmx32g -XX:ObjectAlignmentInBytes=8”

It can be seen that the type word size is 8 bytes, and the compressed pointer is invalid.

 

Let us now increase object alignment to 16 bytes and test it “-Xmx32g -XX:ObjectAlignmentInBytes=16”

It can be seen that the type word size is 4 bytes 0x00067040, and the compressed pointer takes effect.

 

Default Value:

 

The default value is 8 bytes.

 

Note:

 

The tests above were ran using OpenJDK 11.

 

Error:

 

An error is thrown if the value given is not the power of 2, if not within the range of 8 and 256 (inclusive) or below 8 (the minimum is 8).

 

Related Posts:

 

Got something else on mind? Post Your Question

Not the answer you're looking for? Browse other questions tagged
  • jvmargument

  • xx-objectalignmentinbytes

  • x-objectalignmentinbytes

  • JVM startup parameter