Understanding JVM Pointer Compression and Memory Layout
The article explains how the JVM reduces memory consumption on 64‑bit systems by using compressed ordinary object pointers (compressed oops), describes pointer size, alignment and padding, shows C struct and JVM object layout examples, and demonstrates inspection tools like HSDB and XPocket for analyzing object memory footprints.
Java is one of the most popular programming languages today, and the Java Virtual Machine (JVM) is the core runtime that translates bytecode into machine code.
On 32‑bit systems a pointer occupies 4 bytes; on 64‑bit systems it grows to 8 bytes. To reduce memory consumption, the JVM uses compressed oops (ordinary object pointers) to store 8‑byte pointers in 4 bytes.
The size of a pointer is determined by the machine word size. A 32‑bit word is 4 bytes, a 64‑bit word is 8 bytes, and the pointer must be able to address the whole address space.
Memory alignment forces data to be placed at addresses that are multiples of the word size. If a field does not naturally align, the compiler inserts padding bytes.
Example in C: #include struct Test { int a; char b; int c; } test; int main(void) { test.a = 1; test.b = 2; test.c = 3; printf("struct Test size: %d\n", sizeof(test)); return 0; } The struct logically needs 9 bytes (int 4 + char 1 + int 4) but the compiler pads it to 12 bytes, inserting three empty bytes after the char to keep the following int aligned.
JVM objects follow the same principle: object headers and fields are aligned, resulting in padding similar to the C example.
Compressed oops work by shifting the original 8‑byte address right by 3 bits (equivalent to multiplying by 8) and storing the 4‑byte result; the lower 3 bits are always zero. This allows a 4‑byte pointer to address up to 32 GB of heap. When the heap exceeds this limit, compression must be disabled.
Tools for inspecting these details:
HSDB (HotSpot Debugger) provides a visual way to explore JVM internals such as threads, heap, classes, objects, and compiled code.
XPocket is an open‑source plugin container that integrates HSDB and other performance tools, making command‑line debugging more convenient.
Typical workflow to explore an object’s layout:
wget https://a.perfma.net/xpocket/download/XPocket.tar.gz
tar -xvf XPocket.tar.gz
sh xpocket/xpocket.sh # Switch to HSDB plugin
XPocket [system] > use jhsdb@JDK
# Start clhsdb
XPocket [jhsdb] > clhsdb
# Attach to the target JVM process (pid 29516)
XPocket [jhsdb] > attach 29516
# Show heap regions
XPocket [jhsdb : 29516] > universeUse scanoops to locate a Spring‑managed object, then inspect and mem to view its layout and raw words.
XPocket [jhsdb : 29516] > scanoops 0x00000000f0000000 0x00000000f1265ca8 com.poizon.robot.test.BeanTest
XPocket [jhsdb : 29516] > inspect 0x00000000f1060898
XPocket [jhsdb : 29516] > mem 0x00000000f1060898 5The example BeanTest object occupies 40 bytes (5 words) on a 64‑bit JVM with compressed oops. By examining the object header (Mark Word) and the class pointer, you can see how the compression algorithm stores the class reference in 4 bytes.
Understanding these low‑level mechanisms helps diagnose memory usage issues and encourages deeper exploration of JVM internals.
DeWu Technology
A platform for sharing and discussing tech knowledge, guiding you toward the cloud of technology.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.