Metaspace

本文详细解释了JavaMetaspace的作用、空间分配与回收机制,以及如何配置MaxMetaspaceSize和CompressedClassSpaceSize。重点强调了监控和内存控制的重要性。
摘要由CSDN通过智能技术生成

1、什么是 Metaspace

Metaspace 区域位于堆外,所以它的最大内存大小取决于系统内存,而不是堆大小,我们可以指定 MaxMetaspaceSize 参数来限定它的最大内存。

Metaspace 是用来存放 class metadata 的,class metadata 用于记录一个 Java 类在 JVM 中的信息,包括但不限于 JVM class file format 的运行时数据:

1、Klass 结构,可以把它理解为一个 Java 类在虚拟机内部的表示
2、method metadata,包括方法的字节码、局部变量表、异常表、参数信息等
3、常量池
4、注解
5、方法计数器,记录方法被执行的次数,用来辅助 JIT 决策
6、 其他

2、什么时候分配 Metaspace 空间

当一个类被加载时,它的类加载器会负责在 Metaspace 中分配空间用于存放这个类的元数据。

3、什么时候回收 Metaspace 空间

分配给一个类的空间,是归属于这个类的类加载器的,只有当这个类加载器卸载的时候,这个空间才会被释放。

所以,只有当这个类加载器加载的所有类都没有存活的对象,并且没有到达这些类和类加载器的引用时,相应的 Metaspace 空间才会被 GC 释放

4、配置 Metaspace 空间

我们只需要关心两个配置参数:

-XX:MaxMetaspaceSize:Metaspace 总空间的最大允许使用内存,默认是不限制。
-XX:CompressedClassSpaceSize:Metaspace 中的 Compressed Class Space 的最大允许内存,默认值是 1G,这部分会在 JVM 启动的时候向操作系统申请 1G 的虚拟地址映射,但不是真的就用了操作系统的 1G 内存。

5、Metaspace 和 GC

Metaspace 只在 GC 运行并且卸载类加载器的时候才会释放空间。当然,在某些时候,需要主动触发 GC 来回收一些没用的 class metadata,即使这个时候对于堆空间来说,还达不到 GC 的条件。

Metaspace 可能在两种情况下触发 GC:

1、分配空间时:虚拟机维护了一个阈值,如果 Metaspace 的空间大小超过了这个阈值,那么在新的空间分配申请时,虚拟机首先会通过收集可以卸载的类加载器来达到复用空间的目的,而不是扩大 Metaspace 的空间,这个时候会触发 GC。这个阈值会上下调整,和 Metaspace 已经占用的操作系统内存保持一个距离。

2、碰到 Metaspace OOM:Metaspace 的总使用空间达到了 MaxMetaspaceSize 设置的阈值,或者 Compressed Class Space 被使用光了,如果这次 GC 真的通过卸载类加载器腾出了很多的空间,这很好,否则的话,我们会进入一个糟糕的 GC 周期,即使我们有足够的堆内存。

所以大家千万不要把 MaxMetaspaceSize 设置得太小

6、Metaspace默认不受限,那为什么要限制 Metaspace 的大小呢?

  • 告警系统需要知道,为什么 Metaspace 空间以一个异常的速度在消耗,需要有人去看一下发生了什么。
  • 有时候需要限制虚拟内存地址的大小。通常我们感兴趣的是实际消耗内存,但是虚拟内存大小可能会导致虚拟机进程达到系统限制。

如果要限制 Metaspace 大小使得系统更容易被监控,同时不用在乎虚拟地址空间的大小,那么最好只设置 MaxMetaspaceSize 而不用设置 CompressedClassSpaceSize。如果要单独设置,那么最好设置 CompressedClassSpaceSize 为 MaxMetaspaceSize 的 80% 左右。

除了 MaxMetaspaceSize 之外,减小 CompressedClassSpaceSize 的唯一原因是减小虚拟机进程的虚拟内存大小。 但是,如果将 CompressedClassSpaceSize 设置得太低,则可能在用完 MaxMetaspaceSize 之前先用完了 Compressed Class Space。 在大多数情况下,比率为1:2(CompressedClassSpaceSize = MaxMetaspaceSize / 2)应该是安全的。

7、MaxMetaspaceSize 设置为多大合适呢?

那么,你应该将 MaxMetaspaceSize 设置为多大呢? 首先应该是计算预期的 Metaspace 使用量。你可以使用上面给出的数字,然后给每个类约 1K 的 Class Space 和 3~8K 的 Non-Class Space 作为缓冲。

因此,如果你的应用程序计划加载10000个类,那么从理论上讲,你只需要 10M 的 Class Space 和 80M Non-Class Space。

然后,你需要考虑安全系数。在大多数情况下,安全因子 2 是比较安全的。你当然也可以碰运气,设置低一点,但是要做好在碰到 OOM 后调大 Metaspace 空间的准备。

如果设置安全因子为 2,那么需要 20M 的 Class Space 和 160M 的 Non-Class Space,也就是总大小为 180M。因此,在这里 -XX:MaxMetaspaceSize=180M 是一个很好的选择。

设置值:理论值*安全因子

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值