The principle of jvm compression pointer and the detailed explanation of 32g memory compression pointer failure

Directory:
java virtual machine summary

  1. Class file structure analysis
    1). The constant item structure in the class file constant pool
    2). A collection of commonly used attribute tables
  2. Class loading process
    1). Principle and implementation of class loader
  3. Virtual machine structure analysis
    1) .jdk 1.7 and 1.8 version of the method area structure changes
    2). Simple distinction between constant pools
  4. Object structure analysis
    1). Detailed explanation of compressed pointer <<== Current position
  5. gc garbage collection
  6. Object positioning method

Why introduce compressed pointers (clearly skipped)

First understand:
How much memory can be addressed by a 32-bit operating system A: 4g because 2^32=4 * 1024 * 1024=4g
64-bit? Answer: Approximately infinity

Why use a 64-bit operating system? Answer: Because even your computer has more than 4g of memory. If you use 8g of memory on a 32-bit computer, only 4g is effective, and 4g can’t meet our needs.

But what are the problems with 64-bit?
Answer: 64 bits are too long, which burdens us with addressing bandwidth and in-object references

What burden? Look down!

It will cost more space to store the same object in the heap! ! ! !

There is no proof, first of all, we calculate the size of the same object stored in the heap of different operating systems

The following is the number of bytes occupied by an object,

Object header
32-bit system, occupies 8 bytes (markWord4 bytes + kclass4 bytes)
64-bit system, when UseCompressedOops (compressed pointer) is enabled, occupies 12 bytes, otherwise it is 16 bytes (markWord8 bytes + kclass8 bytes, When opening markWord8 bytes + kclass4 bytes)
instance data
boolean 1
byte 1
short 2
char 2
int 4
float 4
long 8
double 8
reference type
32-bit system occupies 4 bytes (because this reference type needs to go to the method area to find class information , So the address is 32 bits, that is, 4 bytes, and 64 bits are 8 bytes)
64-bit system, when UseCompressedOops is turned on, it occupies 4 bytes, otherwise it is 8-byte
aligned padding.
If the value of the object header + instance data is not 8. Multiples, then we will make up some, make up enough multiples of 8.

Let's start with examples

Suppose there is an object

class A{
    
    
	int a;//基本类型
	B b;//引用类型
}

The memory space consumed by the 32-bit operating system is
object header-8 bytes + instance data int type-4 bytes + reference type-4 bytes + supplementary 0 bytes (16 is a multiple of 8) 16 bytes

64-bit operating system
object header-16 bytes + instance data int type-4 bytes + reference type-8 bytes + supplementary 4 bytes (28 is not a multiple of 8 supplements 4 bytes to reach 32 bytes) 32 bytes

The same object needs nearly twice the capacity, (the actual average is 1.5 times), so you need to turn on the compressed pointer:

64-bit pointer to open the compressed object header -12 instance data bytes + int + Type - 4 bytes - 4 bytes + supplementary reference type = 24 bytes 0 bytes
after the opening of the space can reduce the pressure on the stack (the same memory more (Oom is not easy to happen)

How the compressed pointer is implemented

The way the JVM is implemented is to
no longer save all references, but to save a reference every 8 bytes. For example, instead of saving each reference 0, 1, 2..., now only 0, 8, 16... are saved. Therefore, after pointer compression, not all references are saved in the heap, but references are saved at intervals of 8 bytes.
In terms of implementation, the references in the heap are actually stored according to 0x0, 0x1, 0x2... It's just that when the reference is stored in a 64-bit register, the JVM shifts it to the left by 3 bits (equivalent to adding 3 zeros at the end), for example, 0x0, 0x1, 0x2... are converted to 0x0, 0x8, 0x10, respectively. When reading from the register, the JVM can shift 3 bits to the right, discarding the 0 at the end. (Oop is 32 bits in the heap, 35 bits in the register, 2 to the 35th power = 32G. In other words, use 32 bits to reach the heap memory space that the 35-bit oop can reference)
Look carefully at the picture~ carefully Look at the picture~Look at the picture carefully
Insert picture description here

What information will be compressed?
1. Object's global static variables (ie class attributes)
2. Object header information: Under 64-bit platforms, the size of the native object header is 16 bytes, compressed to 12 bytes
3. Object reference type: Under 64-bit platforms, The size of the reference type itself is 8 bytes, and it is 4 bytes after compression.
4. Object array type: On a 64-bit platform, the size of the array type itself is 24 bytes and 16 bytes after compression.

What information will not be compressed?
1. Pointer to non-Heap object
2. Local variable, parameter passing, return value, NULL pointer

to sum up:

In the JVM (regardless of whether it is 32-bit or 64-bit), objects are already aligned on 8-byte boundaries. For most processors, this alignment scheme is optimal. Therefore, the use of compressed oop does not bring any loss, but improves performance.

Compressed pointer 32g pointer failure problem

Speaking of this should be very clear, because the 32nd power of 3 in the register can only address about 32g (not accurate 32g, it may refer to compression failure at 31g), so when your memory exceeds 32g, jvm The compressed pointer is disabled by default, and 64-bit addressing is used to operate. This ensures that all your memory can be addressed, but all objects will become larger. In fact, the comparison after opening is not turned on, 40g objects are stored The number is not comparable to the number of storage of 30g

Guess you like

Origin blog.csdn.net/lioncatch/article/details/105919666