Java 元空间

这里包含一个问题,为何要移除方法区 改用元空间:https://openjdk.java.net/projects/jdk8/features

  • 移除永久代的工作从JDK1.7就开始了。JDK1.7中,存储在永久代的部分数据就已经转移到了Java Heap或者是 Native Heap。
  • 为什么移除持久代。在JDK1.8移除了永久代,添加了元空间
    • 它的大小是在启动时固定好的——很难验证并进行调优。-XX:MaxPermSize
    • HotSpot的内部类型也是Java对象:它可能会在Full GC中被移动,非强类型,难以跟踪调试,需要存储元数据的元数据信息。
    • 简化垃圾回收:对每一个回收集使用专门的元数据迭代器。
    • 可以在GC不进行暂停的情况下并发地释放类数据。
    • 使得原来受限于持久代的一些改进未来有可能实现
  • 元空间的本质和永久代类似,都是对JVM规范中方法区的实现。不过元空间与永久代之间最大的区别在于:元空间并不在虚拟机中,而是使用本地内存。因此,默认情况下,元空间的大小仅受本地内存限制,但可以通过以下参数来指定元空间的大小:
    • -XX:MetaspaceSize,初始空间大小,达到该值就会触发垃圾收集进行类型卸载,同时GC会对该值进行调整:如果释放了大量的空间,就适当降低该值;如果释放了很少的空间,那么在不超过MaxMetaspaceSize时,适当提高该值。
    • -XX:MaxMetaspaceSize,最大空间,默认是没有限制的。
    除了上面两个指定大小的选项以外,还有两个与 GC 相关的属性:
    • -XX:MinMetaspaceFreeRatio,在GC之后,最小的Metaspace剩余空间容量的百分比,减少为分配空间所导致的垃圾收集
    • -XX:MaxMetaspaceFreeRatio,在GC之后,最大的Metaspace剩余空间容量的百分比,减少为释放空间所导致的垃圾收集
  • 元空间的特性
    • 充分利用了Java语言规范中的好处:类及相关的元数据的生命周期与类加载器的一致
    • 每个加载器有专门的存储空间
    • 只进行线性分配
    • 不会单独回收某个类
    • 省掉了GC扫描及压缩的时间
    • 元空间里的对象的位置是固定的
    • 如果GC发现某个类加载器不再存活了,会把相关的空间整个回收掉
    • 元空间的内存分配模型
    • 绝大多数的类元数据的空间都从本地内存中分配
    • 用来描述类元数据的类也被删除了
    • 分元数据分配了多个虚拟内存空间
    • 给每个类加载器分配一个内存块的列表。块的大小取决于类加载器的类型; sun/反射/代理对应的类加载器的块会小一些
    • 归还内存块,释放内存块列表
    • 一旦元空间的数据被清空了,虚拟内存的空间会被回收掉
    • 减少碎片的策略
  • 元空间内存管理
    • 元空间的内存管理由元空间虚拟机来完成。先前,对于类的元数据我们需要不同的垃圾回收器进行处理,现在只需要执行元空间虚拟机的C++代码即可完成。在元空间中,类和其元数据的生命周期和其对应的类加载器是相同的。话句话说,只要类加载器存活,其加载的类的元数据也是存活的,因而不会被回收掉。
    • 准确的来说,每一个类加载器的存储区域都称作一个元空间,所有的元空间合在一起就是我们一直说的元空间。当一个类加载器被垃圾回收器标记为不再存活,其对应的元空间会被回收。在元空间的回收过程中没有重定位和压缩等操作。但是元空间内的元数据会进行扫描来确定Java引用。
    • 元空间虚拟机负责元空间的分配,其采用的形式为组块分配。组块的大小因类加载器的类型而异。在元空间虚拟机中存在一个全局的空闲组块列表。当一个类加载器需要组块时,它就会从这个全局的组块列表中获取并维持一个自己的组块列表。当一个类加载器不再存活,那么其持有的组块将会被释放,并返回给全局组块列表。类加载器持有的组块又会被分成多个块,每一个块存储一个单元的元信息。组块中的块是线性分配(指针碰撞分配形式)。组块分配自内存映射区域。这些全局的虚拟内存映射区域以链表形式连接,一旦某个虚拟内存映射区域清空,这部分内存就会返回给操作系统。
  • 元空间的问题
    • 元空间虚拟机采用了组块分配的形式,同时区块的大小由类加载器类型决定。类信息并不是固定大小,因此有可能分配的空闲区块和类需要的区块大小不同,这种情况下可能导致碎片存在。元空间虚拟机目前并不支持压缩操作,所以碎片化是目前最大的问题。

Leave a Reply

Your email address will not be published. Required fields are marked *

lWoHvYe 无悔,专一