对JVM规范中方法区的实现。java
绝大部分 Java 程序员应该都见过 "java.lang.OutOfMemoryError: PermGen space "这个异常。这里的 “PermGen space”其实指的就是方法区。不过方法区和“PermGen space”又有着本质的区别。前者是 JVM 的规范,然后者则是 JVM 规范的一种实现,而且只有 HotSpot 才有 “PermGen space”,而对于其余类型的虚拟机,如 JRockit(Oracle)、J9(IBM) 并无“PermGen space”。因为方法区主要存储类的相关信息,因此对于动态生成类的状况比较容易出现永久代的内存溢出。最典型的场景就是,在 jsp 页面比较多的状况,容易出现永久代内存溢出。程序员
其实,移除永久代的工做从JDK1.7就开始了。JDK1.7中,存储在永久代的部分数据就已经转移到了Java Heap或者是 Native Heap。但永久代仍存在于JDK1.7中,并没彻底移除,譬如符号引用(Symbols)转移到了native heap;字面量(interned strings)转移到了java heap;类的静态变量(class statics)转移到了java heap。jsp
元空间的本质和永久代相似,都是对JVM规范中方法区的实现。不过元空间与永久代之间最大的区别在于:元空间并不在虚拟机中,而是使用本地内存。所以,默认状况下,元空间的大小仅受本地内存限制,但能够经过如下参数来指定元空间的大小:spa
-XX:MetaspaceSize,初始空间大小,达到该值就会触发垃圾收集进行类型卸载,同时GC会对该值进行调整:若是释放了大量的空间,就适当下降该值;若是释放了不多的空间,那么在不超过MaxMetaspaceSize时,适当提升该值。
-XX:MaxMetaspaceSize,最大空间,默认是没有限制的。内存
除了上面两个指定大小的选项之外,还有两个与 GC 相关的属性:
-XX:MinMetaspaceFreeRatio,在GC以后,最小的Metaspace剩余空间容量的百分比,减小为分配空间所致使的垃圾收集
-XX:MaxMetaspaceFreeRatio,在GC以后,最大的Metaspace剩余空间容量的百分比,减小为释放空间所致使的垃圾收集虚拟机
最后咱们来看一下Metaspace相关的几个JVM参数:string
| 参数名it
|io
做 用class
| |
MetaspaceSize
|
初始化的Metaspace大小,控制Metaspace发生GC的阈值。GC后,动态增长或者下降MetaspaceSize,默认状况下,这个值大小根据不一样的平台在12M到20M之间浮动
| |
MaxMetaspaceSize
|
限制Metaspace增加上限,防止由于某些状况致使Metaspace无限使用本地内存,影响到其余程序,默认为4096M
| |
MinMetaspaceFreeRatio
|
当进行过Metaspace GC以后,会计算当前Metaspace的空闲空间比,若是空闲比小于这个参数,那么虚拟机增加Metaspace的大小,默认为40,即70%
| |
MaxMetaspaceFreeRatio
|
当进行过Metaspace GC以后,会计算当前Metaspace的空闲空间比,若是空闲比大于这个参数,那么虚拟机会释放部分Metaspace空间,默认为70,即70%
| |
MaxMetaspaceExpanison
|
Metaspace增加时的最大幅度,默认值为5M
| |
MinMetaspaceExpanison
|
Metaspace增加时的最小幅度,默认为330KB
|