前言
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被分配于堆外空间,默认最大空间只受限于系统物理内存。