RFR: Implementation of JEP 387: Elastic Metaspace (round two)

Thomas Stüfe thomas.stuefe at gmail.com
Fri Sep 18 13:28:23 UTC 2020


Hi Leo,

On Fri, Sep 18, 2020 at 2:14 PM Leo Korinth <leo.korinth at oracle.com> wrote:

>
> >
> > Finally, why was it chosen that each node could carry precisely two
> > chunk-roots? It seems somewhat easier to have a one-to-one relation
> > between chunk-root and VirtualSpaceNode (when we are already so close
> > to one).
> >
>
> Answering to myself: Because of compressed class space of course. Then we
> could no longer have one huge VirtualSpaceNode for compressed space, and
> VirtualSpaceList would need extra logic for allocating into the compressed
> class address space. Or we would need more levels for the buddy allocator
> in compressed class space so that it could still be one huge node (with a
> huge root-chunk). Each of which is a non-trivial change.
>
>
Some more details:

About the mappings (nodes): as you said, we have the two cases, one where
we reserve them ourselves, with a default size, one where we clamp a node
atop of a pre-existing mapping of arbitrary length. The latter is the
compressed class space case. In the future we may expand or change the
usage, so I think this kind of flexibility is good to have.

Mapping (node) size influences virtual size waste and vma fragmentation.
Larger mappings waste more address space, which still matters on 32bit.
They also waste real memory when living in large paged memory (not a
concern for now). Smaller mappings means we have more of them, therefore
the number of VMAs goes up. So the mapping size is a compromise between
these two concerns. I chose 8MB as default size for a node for no other
reason than it is close to what old Metaspace did. But not much thinking
went into this number. I think we could easily make the nodes larger, e.g.
6-10 root chunks (24-40MB).

--

Why not one root chunk per mapping? Many buddy allocators do that, make the
whole mapping one giant root chunk. But implementation is easier if you
require the starting address of a chunk to be aligned to its size. So, if
we make the whole mapping one giant root chunk, a 4G compressed class space
would have to be aligned to a 4GB starting address. Also, each mapping
would have to be power 2 sized, so we could only have a 2GB or 4GB
compressed class space, but nothing in between.

Other implementations are possible of course, but these restrictions make
the implementation simple, and I liked that. So I did separate mapping
(node) from root chunks, made them a 1:n relation. That way the only
restriction is that a node starting address and size have to be root chunk
aligned, currently 4MB, which as a restriction is not too harsh.

--

Finally, the root chunk size of 4MB was simply chosen because it is
comfortably larger than anything we may want to allocate from Metaspace. I
believe we could make it even smaller, maybe 1MB would be enough (largest
Klass structure can be around 600K I believe).



> Sorry for my confusion.
>

You don't seem confused :) The idea to equal mapping to root chunk 1:1 is
valid and would make matters easier. Had we not
larger-than-default-mappings it would make sense.


>
> Thanks,
> Leo
>

Cheers, Thomas


More information about the hotspot-runtime-dev mailing list