JDK-8244943 : Improve Class Space placement
  • Type: Enhancement
  • Component: hotspot
  • Sub-Component: runtime
  • Affected Version: 15
  • Priority: P4
  • Status: Resolved
  • Resolution: Won't Fix
  • Submitted: 2020-05-13
  • Updated: 2022-06-24
  • Resolved: 2022-06-24
Related Reports
Relates :  
Relates :  
Relates :  
Description
CCS/CDS placement is suboptimal.

Ideally it should be placed in a way to allow for fast narrow class pointer decoding. On most platforms this means low addresses are good (<4G for zero based without shift, <32g for zero based with shift). This is very similar to how the heap is allocated when compressed oops are enabled.

CDS off:

If +UseCompressedOops and +UseCompressedClassPointers, we attempt to place the ccs atop of the heap. The assumption is that the heap has been placed in coops-friendly territory (lower address regions allowing for zero-based or unscaled encoding) and that mapping right above it will yield us a good chance at zero based or unscaled compressed class pointer encoding.

Since JDK-8241825, if -UseCompressedOops and +UseCompressedClassPointers, we attempt to place the ccs at HeapBaseMinAddress (as in "lowest address the platform allows us to map at") for the same reason.

In both cases we try to place the ccs only once, at that exact address. If that does not work out we give up.  We do not try any other attach points.

A better strategy would be to attempt multiple attach points in lower address regions, starting at HeapBaseMinAddress and up to 4G or 32G. Also, to make the placement independent from the heap since the heap may not even be placed in lower regions despite +UseCompressedOops, e.g. if it has been too large. The heap should just be treated as a possible - rather large, maybe - obstacle like any other vma.

Complicating all this is that different architectures may have different ideas of what an optimal encoding base is. Or even restrict the encoding schemes (e.g. aarch64). See also JDK-8243392.

CDS on:

 Here, we only ever use the SharedBaseAddress, which by default lays at 0x800000000. Since CDS=on is pretty much default now, it would make sense to optimize that placement too.

Comments
I don't have time to work on this in the foreseeable future, and we may end up with a different encoding scheme anyway if Lilliput hits. I'll close this for now.
24-06-2022

We could increase the alignment requirement for Metaspace to 4 bits. That way we reach 64G for zero based compressed klass poiner encoding. Done correctly (i.e. not for the whole Metaspace, just for the class space) the loss of memory due to alignment would be not too bad (avg Klass structure is 600-700 bytes, and we would loose, on average, 8 bytes to increased alignment).
19-05-2020

If we move SharedBaseAddress below 32G to a fixed location (say 31G), that would reduce the maximum size of compressed heap by a fixed amount.
19-05-2020

A related issue is that CDS enabled always sets compressed class shift to 3 for compatibility with AOT which generates code with shift hard-coded to 3. But with the default SharedBaseAddress of 0x800000000 we can't use the zero-base optimisation so we end up generating inefficient code with both base and shift non-zero. By moving the default SharedBaseAddress under 32G we could eliminate the instructions that load the base address from every compressed class encode/decode (MOV with 64-bit immediate on x86, EOR on AArch64). I think it makes sense to optimise this case as CDS-on is now the default. I tried a different approach of changing AOT to use zero-shift, but that has some drawbacks and is a wider change than just altering the default SharedBaseAddress, if that's possible.
19-05-2020