jdk8里特有的数据结构用来替代perm
metaspace其实由两大部分组成
Klass Metaspace, NoKlass Metaspace
Klass Metaspace
就是用来存klass
这块内存大小可通过-XX:CompressedClassSpaceSize参数来控制,这个参数前面提到了默认是1G,
但是这块内存也可以没有,假如没有开启压缩指针就不会有这块内存,这种情况下klass都会存在NoKlass Metaspace里
NoKlass Metaspace专门来存klass相关的其他的内容,比如method,constantPool等
JVM 参数
https://www.jianshu.com/p/b448c21d2e71
MetaspaceSize
默认20.8M左右(x86下开启c2模式),主要是控制metaspaceGC发生的初始阈值,也是最小阈值。注意这里并不是设置Metaspace的大小,而是设置其发生GC的阈值。
但是触发metaspaceGC的阈值是不断变化的,与之对比的主要是指Klass Metaspace与NoKlass Metaspace两块committed的内存和。
MaxMetaspaceSize
默认基本是无穷大,但是我还是建议大家设置这个参数,因为很可能会因为没有限制而导致metaspace被无止境使用(一般是内存泄漏)而被OS Kill。
这个参数会限制metaspace(包括了Klass Metaspace以及NoKlass Metaspace)被committed的内存大小,会保证committed的内存不会超过这个值,
一旦超过就会触发GC,这里要注意和MaxPermSize的区别,MaxMetaspaceSize并不会在jvm启动的时候分配一块这么大的内存出来,而MaxPermSize是会分配一块这么大的内存的。
CompressedClassSpaceSize
默认1G,这个参数主要是设置Klass Metaspace的大小,不过这个参数设置了也不一定起作用,前提是能开启压缩指针,
假如-Xmx超过了32G,压缩指针是开启不来的。如果有Klass Metaspace,那这块内存是和Heap连着的。
http://lovestblog.cn/blog/2016/10/29/metaspace/
https://www.jianshu.com/p/b448c21d2e71
http://aoyouzi.iteye.com/blog/2243929