Meta Space是JDK1.8引入的,在JDK1.8使用的是方法区,永久代(Permnament Generation)。
元空间存储的是元信息,使用的是操做系统的本地内存(Metaspace与PermGen之间最大的区别),能够是不连续的,由元空间虚拟机进行管理。能够产生OutOfMemoryErrorhtml
咱们来看下JVM是如何给元数据分配虚拟内存的空间的 java
你能够看到虚拟内存空间是如何分配的(vs1,vs2,vs3) ,以及类加载器的内存块是如何分配的。CL是Class Loader的缩写。面试
要想理解下面这张图,你得搞清楚这些指针都是什么东西。oop
JVM中,每一个对象都有一个指向它自身类的指针,不过这个指针只是指向具体的实现类,而不是接口或者抽象类。布局
对于32位的JVM:性能
_mark : 4字节常量spa
_klass: 指向类的4字节指针 对象的内存布局中的第二个字段( _klass,在32位JVM中,相对对象在内存中的位置的偏移量是4,64位的是8)指向的是内存中对象的类定义。操作系统
64位的JVM:代理
_mark : 8字节常量指针
_klass: 指向类的8字节的指针
开启了指针压缩的64位JVM: _mark : 8字节常量
_klass: 指向类的4字节的指针
类指针压缩空间(Compressed Class Pointer Space)
只有是64位平台上启用了类指针压缩才会存在这个区域。对于64位平台,为了压缩JVM对象中的_klass指针的大小,引入了类指针压缩空间(Compressed Class Pointer Space)。
压缩指针后的内存布局
指针压缩概要
使用-XX:+UseCompressedOops压缩对象指针 "oops"指的是普通对象指针("ordinary" object pointers)。 Java堆中对象指针会被压缩成32位。 使用堆基地址(若是堆在低26G内存中的话,基地址为0)
使用-XX:+UseCompressedClassPointers选项来压缩类指针
对象中指向类元数据的指针会被压缩成32位
类指针压缩空间会有一个基地址
类指针压缩空间只包含类的元数据,好比InstanceKlass, ArrayKlass 仅当打开了UseCompressedClassPointers选项才生效 为了提升性能,Java中的虚方法表也存放到这里 这里到底存放哪些元数据的类型,目前仍在减小
元空间包含类的其它比较大的元数据,好比方法,字节码,常量池等。
元空间的内存管理由元空间虚拟机来完成。先前,对于类的元数据咱们须要不一样的垃圾回收器进行处理,如今只须要执行元空间虚拟机的C++代码便可完成。在元空间中,类和其元数据的生命周期和其对应的类加载器是相同的。话句话说,只要类加载器存活,其加载的类的元数据也是存活的,于是不会被回收掉。
准确的来讲,每个类加载器的存储区域都称做一个元空间,全部的元空间合在一块儿就是咱们一直说的元空间。当一个类加载器被垃圾回收器标记为再也不存活,其对应的元空间会被回收。在元空间的回收过程当中没有重定位和压缩等操做。可是元空间内的元数据会进行扫描来肯定Java引用。
元空间虚拟机负责元空间的分配,其采用的形式为组块分配。组块的大小因类加载器的类型而异。在元空间虚拟机中存在一个全局的空闲组块列表。当一个类加载器须要组块时,它就会从这个全局的组块列表中获取并维持一个本身的组块列表。当一个类加载器再也不存活,那么其持有的组块将会被释放,并返回给全局组块列表。类加载器持有的组块又会被分红多个块,每个块存储一个单元的元信息。组块中的块是线性分配(指针碰撞分配形式)。组块分配自内存映射区域。这些全局的虚拟内存映射区域以链表形式链接,一旦某个虚拟内存映射区域清空,这部份内存就会返回给操做系统。
上图展现的是虚拟内存映射区域如何进行元组块的分配。类加载器1和3代表使用了反射或者为匿名类加载器,他们使用了特定大小组块。 而类加载器2和4根据其内部条目的数量使用小型或者中型的组块。
(1)-XX:MetaspaceSize,初始空间大小,达到该值就会触发垃圾收集进行类型卸载,同时GC会对该值进行调整:若是释放了大量的空间,就适当下降该值;若是释放了不多的空间,那么在不超过MaxMetaspaceSize时,适当提升该值。
(2)-XX:MaxMetaspaceSize,最大空间,默认是没有限制的。
若是没有使用-XX:MaxMetaspaceSize来设置类的元数据的大小,其最大可利用空间是整个系统内存的可用空间。JVM也能够增长本地内存空间来知足类元数据信息的存储。 可是若是没有设置最大值,则可能存在bug致使Metaspace的空间在不停的扩展,会致使机器的内存不足;进而可能出现swap内存被耗尽;最终致使进程直接被系统直接kill掉。若是类元数据的空间占用达到MaxMetaspaceSize设置的值,将会触发对象和类加载器的垃圾回收。
(3)-XX:MinMetaspaceFreeRatio,在GC以后,最小的Metaspace剩余空间容量的百分比,减小为分配空间所致使的垃圾收集
(4)-XX:MaxMetaspaceFreeRatio,在GC以后,最大的Metaspace剩余空间容量的百分比,减小为释放空间所致使的垃圾收集
参考文章:
(1)https://www.cnblogs.com/williamjie/p/9558094.html
(2)java面试:你真的知道metaspace?? https://www.jianshu.com/p/cd34d6f3b5b4