了解 JVM 堆打印输出中的元空间行
- 2024-11-14 08:29:00
- admin 原创
- 18
问题描述:
在 Java 8 堆打印输出中,您可能会看到如下行:
元空间 已用2425K,容量4498K,已提交4864K,已保留1056768K
https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/considerations.html尝试解释这一行:
在以 Metaspace 开头的行中,used值是用于加载类的空间量。capacity 值是当前分配的块中可用于元数据的空间量。committed值是可用于块的空间量。reserved值是为元数据保留(但不一定已提交)的空间量。
再次,来自上面的链接:
向操作系统请求空间,然后将其划分为块。类加载器从其块中为元数据分配空间(每个块与特定的类加载器绑定)。
我想知道每个字段的含义(已使用、容量、已提交、保留),但我很难理解上述定义。
我的理解是,元空间是从 JVM 进程的虚拟地址空间中划分出来的。JVM 在启动时根据 -XX:MetaspaceSize 保留初始大小,该值具有未记录的、特定于平台的默认值。我假设保留是指元空间的总大小。空间被分成块。我不确定每个块是否具有相同的大小。每个块包含与单个类加载器关联的类元数据。
在我看来,容量和已提交空间听起来像是可用空间(基于链接中的定义)。由于元数据存储在块中,因此我认为已使用空间 + 容量等于已提交空间,但事实并非如此。也许已提交空间意味着已使用的保留空间,但已使用空间又意味着什么呢?已使用空间由元数据使用?那么,还有哪些其他方式可以使用这些空间呢?
我希望你能明白我的困惑。如果能澄清一下定义,我将非常感激。
解决方案 1:
元空间由一个或多个虚拟空间组成。虚拟空间是从操作系统获得的连续地址空间区域。它们是按需分配的。分配后,虚拟空间会从操作系统保留内存,但尚未提交。元空间保留内存是所有虚拟空间的总大小。
虚拟空间内的分配单元是 Metachunk(或简称为 Chunk)。当从虚拟空间分配新的块时,会提交相应的内存。元空间提交的内存是所有块的总大小。
块的大小可能不同。当 ClassLoader 被垃圾回收时,属于它的所有 Metachunks 都会被释放。空闲的块保存在全局空闲列表中。元空间容量是所有已分配(即非空闲)块的总大小。
新的块分配
在空闲列表中寻找一个现有的空闲块。
如果没有合适的空闲块,则从当前虚拟空间中分配一个新的块。
若当前虚拟空间已耗尽,则预留新的虚拟空间。
类元数据分配在一个块内。块可能不包含来自多个 ClassLoader 的数据,但一个 ClassLoader 可能有多个块。使用的元空间是所有块中的所有类元数据的总大小。
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理必备:盘点2024年13款好用的项目管理软件