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

时间:2016-11-30 14:54:17

标签: java linux java-8 jvm metaspace

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

  

Metaspace 已使用 2425K,容量 4498K,已提交 4864K,已保留 1056768K

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

  

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

再次,从以上链接:

  

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

我想知道每个字段的含义(使用,容量,承诺,保留),但我很难理解上述定义。

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

容量已提交听起来像是我的可用空间(基于链接中的定义)。由于元数据存储在块中,因此我假设使用的+容量将等于已提交,但事实并非如此。也许承诺意味着使用的保留空间,但那么使用的意思是什么?元数据使用的空间?那么,还有什么方法可以使用这个空间?

我希望你看到我的困惑。我希望澄清这些定义。

1 个答案:

答案 0 :(得分:31)

Metaspace layout

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

虚拟空间内的分配单元是Metachunk(或简称为Chunk)。从虚拟空间分配新块时,相应的内存已提交。元数据空间已提交内存是所有数据块的总大小。

Chunks的大小可能不同。当ClassLoader被垃圾收集时,属于它的所有Metachunk都被释放。全局免费列表中保留了免费块。元空间容量是所有分配的(即非免费)块的总大小。

新的块分配

  1. 在免费列表中查找现有的免费块。
  2. 如果没有合适的空闲块,请从当前虚拟空间中分配一个新空间。
  3. 如果当前虚拟空间已用尽,请保留新的虚拟空间。
  4. 类元数据在块中分配。块可能不包含来自多个ClassLoader的数据,但是一个ClassLoader可能包含多个块。元空间使用是所有块中所有类元数据的总大小。