max heap size for compressed oops

Matthias Wahl matthiaswahl at
Fri Dec 11 15:13:15 UTC 2015

Thanks for your quick reply.

This makes complete sense.

It sheds some light on how compressed oops work.
Unfortunately it does not answer my initial question.

In the mean time i was able to figure out that we actually have
compressed oops up to 32 GB:

$ java -XX:+UnlockDiagnosticVMOptions -XX:+PrintCompressedOopsMode
-Xmx32g -Xms32g -XX:+UseCompressedOops -version
Java HotSpot(TM) 64-Bit Server VM warning: Max heap size too large for
Compressed Oops
java version "1.8.0_60"
Java(TM) SE Runtime Environment (build 1.8.0_60-b27)
Java HotSpot(TM) 64-Bit Server VM (build 25.60-b23, mixed mode)


$ java -XX:+UnlockDiagnosticVMOptions -XX:+PrintCompressedOopsMode
-Xmx31999m -Xms31999m -XX:+UseCompressedOops -version

Protected page at the reserved heap base: 0x000000011e000000 / 2097152 bytes

heap address: 0x000000011e200000, size: 30502 MB, Compressed Oops with
base: 0x000000011e1ff000

Narrow klass base: 0x00000008d6263000, Narrow klass shift: 0
Compressed class space size: 1073741824 Address: 0x00000008d6263000 Req
Addr: 0x0000000890800000
java version "1.8.0_60"
Java(TM) SE Runtime Environment (build 1.8.0_60-b27)
Java HotSpot(TM) 64-Bit Server VM (build 25.60-b23, mixed mode)


So I am still searching for a reason for the 30.5GB suggestion.
But I think we can narrow it down to some GC (G1) performance hint.

Does anybody have a clue on why heaps > 30.5 GB may induce really worse
performance characteristics? Be it G1 or CMS Garbage Collector.

Thank you!

Just ignore this mail if you think it's not the right place for such


Am 12/9/15 um 6:11 PM schrieb Andrew Haley:
> On 12/09/2015 04:04 PM, Matthias Wahl wrote:
>> Do you know any reason for limiting the heap size to 30.5 GB instead of
>> 32 GB?
> The interesting thing you can do is use -XX:+PrintAssembly and have a
> look.  My guess is that it has to do with zero-based compressed OOPs:
> if you can use zero as the base pointer you don't have to dedicate a
> register to the job and the compressing/decompressing code is faster.
> A narrow OOP is computed by
>   oop_address == 0  ? 0 : (oop_address - heap_base) >> shift
> The OOP at 0 is a null, of course.
> If the heap base is zero, you can encode an OOP with a single
> shift instruction:
>      lsr x0, x0, #3
> But if the heap base is not zero, encoding an OOP gets nasty:
>      subs x0, x0, xheapbase
>      csel x0, x0, xzr, cs
>      lsr  x0, x0, #3
> Here there are three instructions, one of them conditional.  In the
> commonest case most modern processors can do the shifting in parallel
> with some other operation, so the cost of compressed OOPs is often
> zero as long as the heap base is zero.  But there's no way that the
> three instructions used encoding an OOP with a nonzero heap base are
> gong to cost nothing.
> So why is there a difference between 30.5G and 32G?  Because in
> practice the JVM sits in the bottom 1.5G or so of memory and the heap
> is immediately above it, so the heap base for compressed OOPs can be
> zero.
> Does that make sense?
> Andrew.

More information about the discuss mailing list