元空间(metaspace)概念
在之前介绍的分代垃圾回收算法中,我们一直有一个永久代存在,叫 PermGen,内存上它是挨着堆的。为了垃圾回收方便,HotSpot 在永久代上一直是使用老年代的垃圾回收算法。
永久代主要存放以下数据:
- JVM internal representation of classes and their metadata
- Class statics
- Interned strings
从 JDK7 开始,JDK 开发者们就有消灭永久代的打算了。有部分数据移到永久代之外了:
- Symbols => native memory
- Interned strings => Java Heap
- Class statics => Java Heap
到了 JDK8,这个工作终于完成了,彻底废弃了 PermGen,Metaspace 取而代之。
什么是 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、 其他
虽然每个 Java 类都关联了一个 java.lang.Class 的实例,而且它是一个贮存在堆中的 Java 对象。但是类的 class metadata 不是一个 Java 对象,它不在堆中,而是在 Metaspace 中。
什么时候分配 Metaspace 空间
当一个类被加载时,它的类加载器会负责在 Metaspace 中分配空间用于存放这个类的元数据。
