For 32-bit machines, the maximum memory a process can use is 4G. If the process needs to use more memory, use a 64-bit machine.

For Java processes, when OOP is only 32 bits, only 4G memory can be referenced. Therefore, if larger heap memory needs to be used, a 64-bit JVM needs to be deployed. This way, oop is 64 bits, and the referable heap memory is larger.

An OOP (Ordinary Object Pointer) is a handle used by the JVM to represent a referenced object.

In the heap, 32-bit object references account for 4 bytes, while 64-bit object references account for 8 bytes. That is, a 64-bit object reference is twice the size of a 32-bit object reference.

64-bit JVMS, while supporting larger heaps, introduce performance problems due to larger object references:

  1. Increased GC overhead

64-bit object references take up more heap space, leaving less space for other data, speeding up GC and making GC more frequent.

  1. Reduce CPU cache hit ratio

As 64-bit object references grow, the CPU will have less OOP to cache, reducing CPU caching efficiency.

In order to maintain 32-bit performance, OOP must be 32-bit. So how do you use 32-bit OOP to reference larger heap memory?

The answer is CompressedOops.

Instead of saving all references, the JVM implements one reference every eight bytes. For example, it used to save each reference 0, 1, 2… , now only save 0, 8, 16… . Therefore, when the pointer is compressed, instead of all references being stored in the heap, references are stored at 8-byte intervals.

Implementationally, references in the heap are still 0x0, 0x1, 0x2… Store it. It’s just that when the reference is stored in a 64-bit register, the JVM moves it three bits to the left (equivalent to adding three zeros to the end), such as 0x0, 0x1, 0x2… Is converted to 0x0, 0x8, 0x10, respectively. When read from a register, the JVM can shift three bits to the right, discarding trailing zeros. Oop is 32 bits in heap, 35 bits in register, 2 ^ 35 =32G. That is, using 32 bits to reach the heap memory space that oop can reference with 35 bits.)

In the JVM (whether 32-bit or 64-bit), objects are already aligned at 8-byte boundaries. This alignment scheme is optimal for most processors. So using compressed OOP costs nothing and improves performance.

The Oracle JDK will enable compressed Pointers by default on 64-bit systems starting with 6 Update 23.

The 32-bit HotSpot VM does not support the UseCompressedOops parameter, only the 64-bit HotSpot VM does.

For heaps between 4G and 32GB in size, compressed OOP should be used.

View the working mode of the compression pointer

In the VM startup, can set – XX: XX: + UnlockDiagnosticVMOptions – + PrintCompressedOopsMode parameter to confirm the working mode of compression pointer.

JDK 7

Compressed pointer is enabled by default:

$ java -server -Xms2G -Xmx2G -XX:+UseConcMarkSweepGC -XX:+UnlockDiagnosticVMOptions -XX:+PrintCompressedOopsMode -version

heap address: 0x000000077ae00000, size: 2130 MB, zero based Compressed Oops

java version "1.7.0 _79"
Java(TM) SE Runtime Environment (build 1.7.0_79-b15)
Java HotSpot(TM) 64-Bit Server VM (build 24.79-b02, mixed mode)
Copy the code

JDK 8

Compressed pointer is enabled by default:

$ java -server -Xms2G -Xmx2G -XX:+UseConcMarkSweepGC -XX:+UnlockDiagnosticVMOptions -XX:+PrintCompressedOopsMode -version

heap address: 0x0000000080000000, size: 2048 MB, Compressed Oops mode: 32-bit

Narrow klass base: 0x0000000000000000, Narrow klass shift: 3
Compressed class space size: 1073741824 Address: 0x000000013fe20000 Req Addr: 0x0000000100000000
java version "1.8.0 comes with _121"
Java(TM) SE Runtime Environment (build 1.8.0_121-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.121-b13, mixed mode)
Copy the code

To close the compression pointer:

$ java -server -Xms2G -Xmx2G -XX:+UseConcMarkSweepGC -XX:-UseCompressedOops -XX:+UnlockDiagnosticVMOptions -XX:+PrintCompressedOopsMode -version
java version "1.8.0 comes with _121"
Java(TM) SE Runtime Environment (build 1.8.0_121-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.121-b13, mixed mode)
Copy the code

Compare the

Test environment: JDK 1.8.0_121

The test code

import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;
public class IntegerApplication {
	public static void main(String[] args) {
		List<Integer> intList = new LinkedList<>();
		for (int i = 0; i < 2000000; i++) {
			Integer number = new Integer(1);
			intList.add(number);
		}
		Scanner scanner = new Scanner(System.in);
		System.out.println("application is running..."); String tmp = scanner.nextLine(); System.exit(0); }}Copy the code

Use Eclipse Memory Analyzer to view the number and size of Integer objects

First run the IntegerApplication program, and then check the object allocation through MAT.

Enable compression pointer

The compressed pointer is enabled by default (-xx :+UseCompressedOops).

$ java IntegerApplication
application is running...
Copy the code

Each Integer has the following size:

64(Mark Word)+32(Compressed oops)+32(int)=128bits=16bytes

The total size of all integers is:

2000256*16=32004096bytes

Close compressed pointer

Set the parameter -xx: -usecompressedoops to close the compression pointer.

$ java -XX:-UseCompressedOops IntegerApplication
application is running...
Copy the code

Each Integer has the following size:

64(Mark Word)+64(Compressed oops)+32(int)=160bits=20bytes

Since JVM memory allocation needs to be aligned by word width, for 64-bit JVMS, word width is 8 bytes. Thus, an Integer actually occupies 24bytes, or 192bits.

The total size of all integers is:

2000256*24=48006144bytes

As you can see from the above example, the OOP size does become 32 bits after the compression pointer is turned on, and the actual test results are consistent with the theoretical analysis.

Object Header

Object Header on a 64bit VM with compressed oops

Object Header on a 64bit VM without compressed oops

Object Header on a 32bit VM


reference

Scott Oaks, the Definitive Guide to Java Performance

www.javacodegeeks.com/2016/05/com…

Rednaxelafx.iteye.com/blog/101007…

Gist.github.com/arturmkrtch…

Personal public account

For more articles, please pay attention to the public number: binary road