一、Metaspace介绍
JDK 8 开始把类的元数据放到本地堆内存(native heap)中,这一块区域就叫 Metaspace,中文名叫元空间。
使用本地内存有什么好处呢?最直接的表现就是OOM问题将不复存在,因为默认的类的元数据分配只受本地内存大小的限制,也就是说本地内存剩余多少,理论上Metaspace就可以有多大(貌似容量还与操作系统的虚拟内存有关?这里不太清楚),这解决了空间不足的问题。不过,让 Metaspace 变得无限大显然是不现实的,因此我们也要限制 Metaspace 的大小:使用 -XX:MaxMetaspaceSize 参数来指定 Metaspace 区域的大小。JVM 默认在运行时根据需要动态地设置 MaxMetaspaceSize 的大小。
二、JDK1.7 和 JDK1.8 内存区别
- 去除了PermGen,Native Memory中新增了Metaspace
- 静态变量和常量移到了Heap Space
- 类元数据移到了Metaspace
三、Metaspace 和 PermGen 比较
PermGen的劣势
- 固定的PermSize,大小很难确定并且很难进行扩展 -XX:MaxPermSize
-XX:PermSize - 在进行full GC时PermGen中的class meta对象有可能会被移动
- 发生java.lang.OutOfMemoryError: PermGen error时
应用程序要清除与class关联的所有引用
要么更改MaxPermSize重启应用 - 需要meta-classmeta对象对classmeta对象进行描述
- 垃圾回收效率较低,需要进行对整个PermGen进行扫描
Metaspace的优势
- 类和类元数据的生命周期与类加载器一致
- Metaspace的空间分配是线性的,可随类加载的数量进行线性的扩展,默认情况下只与native memory大小有关
- 元数据的位置在native memory中的位置是固定的
- GC时不会对metaspace空间进行扫描,节省了扫描和压缩的时间(如果设置了Metaspace的大小,当到达该Metaspace的阀值也会进行full GC)
- 减小了full gc的时间