前言

JDK 7 以前都是使用PermGen,到了JDK 8之后,改为使用MetaSpace。

PermGen

PermGen Space的全称是Permanent Generation space, 是指内存的永久保存区,一般称为永久带。

这一部分用于存放Class和Meta的信息,Class在被 Load的时候被放入PermGen Space区域,Class和存放Instance的Heap区域不同, GC不会在主程序运行期对PermGen Space进行清理。

MaxPermSize设置过小的时候会出现“java.lang.OutOfMemoryError: PermGen space”。

移除PermGen原因

每次我们都需要配置-XX:PermSize以及-XX:MaxPermSize来控制这块内存的大小。但是具体配置多大,不好控制。太小容易溢出,太大了容易浪费。一种可能就是使用MetaSpace空间替换。

Metaspace

由下面2部分构成,由所有的classloader共享的。

  • Klass Metaspace

存在klass的(klass就是class在jvm运行的数据结构)

  • NoKlass Metaspace

存在klass相关的内容的,比如:method,constantPool等。

MetaspaceSize

  • 初始化的Metaspace大小,控制元空间发生GC的阈值。GC后,动态增加或降低。
  • 含义是指Metaspace扩容时触发FullGC的初始化阈值,也就是最小的阈值。
  • 如果没有配置,默认大小21807104(约20.8m)
  • 如果配置了,那么触发Full GC的阈值就是这个配置的值。
  • 尽量配置,不然刚开始容易Full GC

MaxMetaspaceSize

  • 限制本地内存分配给类元数据的大小。如果没有指定这个参数,元空间会在运行时根据需要动态调整。
  • 如果MaxMetaspaceSize设置太小,可能会导致频繁FullGC,甚至OOM
  • Metaspace被分配于堆外空间,默认最大空间只受限于系统物理内存。

参考