我们深入研究元空间的架构。我们描述了各个层和组件,以及它们是如何协同工作的。
这对那些想要破解hotspot和Metaspace或者至少真正理解内存的去向以及为什么我们不能仅仅使用malloc的人来说是很有趣的。
与大多数其他非平凡的分配器一样,元空间是在层中实现的。
在底部,内存是在操作系统的大区域中分配的。在中间,我们将这些区域分割成不太大的块,然后交给类装入器。
在顶部,类装入器将这些块分割为调用程序代码。
元空间的底层:虚拟空间列表VirtualSpaceList
在最底层(在最粗的粒度上),Metaspace的内存是保留的,并通过类似mmap(3)的虚拟内存调用从操作系统按需提交内存。这种情况发生在2MB大小的区域(在64位平台上)。
这些映射区域作为节点保存在名为VirtualSpaceList的全局链接列表中。
每个节点管理一个高水位线,将已提交的空间与仍然未提交的空间分开。当分配达到最高水位线时,将按需提交新页面。为了避免过于频繁地调用操作系统,保留了一点空间。
直到节点完全用完为止。然后,分配一个新节点并将其添加到列表中。旧节点正在“失效”。
内存是从名为MetaChunk的块节点分配的。它们有三种尺寸,分别命名为specialized、small和medium—命名具有历史意义—通常为1K/4K/64K
VM元空间metaspace的内存结构
VirtualSpaceList及其节点是全局结构,而Metachunk由一个类装入器拥有。因此,VirtualSpaceList中的单个节点可能包含来自不同类装入器的块: