了解 JVM 堆打印输出中的元空间行

Understanding metaspace line in JVM heap printout

在 Java 8 堆打印输出中,您可能会看到如下一行:

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

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

In the line beginning with Metaspace, the used value is the amount of space used for loaded classes. The capacity value is the space available for metadata in currently allocated chunks. The committed value is the amount of space available for chunks. The reserved value is the amount of space reserved (but not necessarily committed) for metadata.

再次从上面link:

Space is requested from the OS and then divided into chunks. A class loader allocates space for metadata from its chunks (a chunk is bound to a specific class loader).

我想知道每个字段的含义(used、capacity、committed、reserved),但我很难理解上面的定义。

我的理解是metaspace是从JVM进程的虚拟地址space中分出来的。 JVM 在启动时保留一个基于 -XX:MetaspaceSize 的初始大小,它有一个未记录的、特定于平台的默认值。我假设 reserved 指的是 metaspace 的总大小。 space 被分成块。我不确定每个块是否具有相同的大小。每个块包含与单个 class 加载器关联的 class 元数据。

Capacitycommitted 对我来说听起来像是免费的 space(基于 link ).由于元数据存储在块中,因此我假设已用 + 容量等于已提交,但事实并非如此。也许 committed 意味着 reserved space 被使用,但是 used 意味着什么? Used space 被元数据使用?那么,还有哪些方法可以使用space?

希望你看到我的困惑。我将不胜感激对定义的澄清。

Metaspace 由一个或多个虚拟 Space 组成。虚拟 Space 是从 OS 获得的连续地址 space 的区域。它们是按需分配的。分配后,虚拟 Space 从 OS 保留 内存,但尚未 提交 它。 Metaspace reserved 内存是所有 Virtual Spaces 的总大小。

Virtual Space 中的分配单元是 Metachunk(或简称为 Chunk)。当从 Virtual Space 分配新块时,相应的内存 committed。 Metaspace committed内存是所有chunk的总大小

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

新块分配

  1. 在空闲列表中查找现有的空闲块。
  2. 如果没有合适的free chunk,从当前Virtual分配一个新的Space。
  3. 如果当前的虚拟Space用完了,保留一个新的虚拟Space。

Class 元数据在块内分配。块可能不包含来自多个 ClassLoader 的数据,但一个 ClassLoader 可能有多个块。 Metaspace used 是来自所有块的所有 class 元数据的总大小。