理解JVM堆打印中的元空间线

22
在Java 8堆转储(printout)中,您可能会看到如下行:

Metaspace used 2425K, capacity 4498K, committed 4864K, reserved 1056768K

https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/considerations.html 尝试解释这一行:

在以Metaspace开头的行中,used 值是用于加载类的空间量。 capacity 值是当前已分配块中元数据(metadata)的可用空间。 committed 值是可用于块的空间量。 reserved 值是为元数据保留(但不一定分配)的空间量。

再次引用上面的链接:

空间从操作系统(OS)请求,然后分成块。类加载器(loader)从其块(chunk)为元数据(metadata)分配空间(chunk绑定到特定类加载器)。

我想知道每个字段的含义(used、capacity、committed、reserved),但我很难理解上面的定义。
我的理解是,Metaspace是从JVM进程的虚拟地址空间中划分出来的。JVM在启动时根据-XX:MetaspaceSize基于未经记录的平台特定默认值来预留初始大小。我假设reserved指的是metaspace的总大小。该空间被分成块(chunk)。我不确定每个块(chunk)的大小是否相同。每个块(chunk)包含与单个类加载器(loader)关联的类元数据(metadata)。

容量已承诺的听起来对我来说像是剩余空间(根据链接中的定义)。由于元数据存储在块内,因此我会认为已用 + 容量将等于已承诺,但实际上并不是这样。也许已承诺的意思是保留的已用空间,但那么已用指什么?元数据使用的已用空间?那么,还有哪些其他方式可以利用空间呢?

希望你能理解我的困惑。我希望能就这些定义得到澄清。

1个回答

53

Metaspace布局

Metaspace由一个或多个虚拟空间组成。虚拟空间是从操作系统获取的连续地址空间区域。它们是按需分配的。当分配时,虚拟空间从操作系统中保留内存,但尚未提交。Metaspace保留内存是所有虚拟空间的总大小。

虚拟空间内的分配单元是Metachunk(或简称Chunk)。当从虚拟空间分配新的chunk时,对应的内存将被提交。Metaspace提交内存是所有chunk的总大小。

chunks的大小可能不同。当一个ClassLoader被垃圾回收时,属于它的所有Metachunks都会被释放。空闲的chunks会在全局空闲列表中维护。Metaspace容量是所有已分配(即非空闲)chunk的总大小。

新的chunk分配

  1. 查找空闲列表中是否有现有的可用chunk。
  2. 如果没有合适的空闲chunk,则从当前虚拟空间分配一个新的chunk。
  3. 如果当前虚拟空间已用尽,则保留一个新的虚拟空间。

类元数据在一个chunk内分配。chunk可能不包含来自多个ClassLoader的数据,但一个ClassLoader可能具有多个chunks。Metaspace已使用是所有chunk中所有类元数据的总大小。


1
一如既往的好答案。这个链接可能仍然对一些人有用 :) https://stuefe.de/posts/metaspace/metaspace-architecture/ - Juraj Martinka

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接