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

标签 java linux java-8 jvm metaspace

在 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.

同样,从上面的链接:

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),但我很难理解上面的定义。

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

Capacitycommitted 对我来说听起来像是自由空间(基于链接中的定义)。由于元数据存储在 block 中,因此我假设已用 + 容量等于已提交,但事实并非如此。也许提交意味着使用的保留空间,但是使用意味着什么?元数据使用的已用空间?那么,还有哪些其他的空间利用方式呢?

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

最佳答案

Metaspace layout

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

Virtual Space 内部的分配单元是 Metachunk(或简称为 Chunk)。当从虚拟空间分配新 block 时,相应的内存将提交。元空间提交内存是所有 block 的总大小。

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

新 block 分配

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

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

关于java - 了解 JVM 堆打印输出中的元空间行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40891433/

相关文章:

java - Spark : Remove Content-Type header

java - Java中运行DOS命令的问题

java - 将事件监听器放在不同的类中会更好吗?

linux - 我希望我的网站有 "case in-sensitive"网址

linux - 内存监控 bash 脚本的 CPU 使用率相当高

java - 过滤器中的顺序 - 这重要吗?

java - 为什么 LocalDate、LocalTime 和 Stream 对象使用工厂方法 of() 而不是构造函数?

java - 强制调用专用方法

linux - 通过命令行 ubuntu 14.04 添加带有现有文本文件的新文本行

Java 8 - 填充 ArrayList