• 深入探究JVM(2)


    Java 8彻底将永久代移除出了HotSpot JVM,将其原有的数据迁移至Java Heap或Metaspace。这一篇文章我们来总结一下Metaspace(元空间)的特性。如有错误,敬请指出,谢谢~


    一、引言:永久代为什么被移出HotSpot JVM了?

    详见:JEP 122: Remove the Permanent Generation 
    原因主要有两个:

    • 1、由于Permanent Generation内存经常不够用或发生内存泄露,引发恼人的java.lang.OutOfMemoryError: PermGen (在Java Web开发中非常常见)。
    • 2、移除Permanent Generation可以促进HotSpot JVM与 JRockit VM的融合,因为JRockit没有永久代。

    This is part of the JRockit and Hotspot convergence effort. JRockit customers do not need to configure the permanent generation (since JRockit does not have a permanent generation) and are accustomed to not configuring the permanent generation.

    根据上面的各种原因,永久代最终被移除,方法区移至Metaspace,字符串常量移至Java Heap

    二、探秘元空间

    由于Metaspace的资料比较少,这里主要是依据Oracle官方的Java虚拟机规范及Oracle Blog里的几篇文章来总结的。 
    首先,Metaspace(元空间)是哪一块区域?官方的解释是:

    In JDK 8, classes metadata is now stored in the native heap and this space is called Metaspace.

    也就是说,JDK 8开始把类的元数据放到本地化的堆内存(native heap)中,这一块区域就叫Metaspace,中文名叫元空间。

    1、优点

    使用本地化的内存有什么好处呢?最直接的表现就是java.lang.OutOfMemoryError: PermGen 空间问题将不复存在,因为默认的类的元数据分配只受本地内存大小的限制,也就是说本地内存剩余多少,理论上Metaspace就可以有多大(貌似容量还与操作系统的虚拟内存有关?这里不太清楚),这解决了空间不足的问题。不过,让Metaspace变得无限大显然是不现实的,因此我们也要限制Metaspace的大小:使用-XX:MaxMetaspaceSize参数来指定Metaspace区域的大小。JVM默认在运行时根据需要动态地设置MaxMetaspaceSize的大小。 
    除此之外,它还有以下优点(没有完全理解,先贴出来吧,来自StackOverflow):

    • Take advantage of Java Language Specification property : Classes and associated metadata lifetimes match class loader’s
    • Linear allocation only
    • No individual reclamation (except for RedefineClasses and class loading failure)
    • No GC scan or compaction
    • No relocation for metaspace objects

    2、垃圾回收

    如果Metaspace的空间占用达到了设定的最大值,那么就会触发GC来收集死亡对象和类的加载器。根据JDK 8的特性,G1和CMS都会很好地收集Metaspace区(一般都伴随着Full GC)。 
    为了减少垃圾回收的频率及时间,控制吞吐量,对Metaspace进行适当的监控和调优是非常有必要的。如果在Metaspace区发生了频繁的Full GC,那么可能表示存在内存泄露或Metaspace区的空间太小了。

    3、新增参数

    • -XX:MetaspaceSize是分配给类元数据空间(以字节计)的初始大小(Oracle逻辑存储上的初始高水位,the initial high-water-mark ),此值为估计值。MetaspaceSize的值设置的过大会延长垃圾回收时间。垃圾回收过后,引起下一次垃圾回收的类元数据空间的大小可能会变大。
    • -XX:MaxMetaspaceSize是分配给类元数据空间的最大值,超过此值就会触发Full GC,此值默认没有限制,但应取决于系统内存的大小。JVM会动态地改变此值。
    • -XX:MinMetaspaceFreeRatio表示一次GC以后,为了避免增加元数据空间的大小,空闲的类元数据的容量的最小比例,不够就会导致垃圾回收。
    • -XX:MaxMetaspaceFreeRatio表示一次GC以后,为了避免增加元数据空间的大小,空闲的类元数据的容量的最大比例,不够就会导致垃圾回收。

    4、监控与调优(待补充)

    VisualVM,jstat,jstack可以监测元空间的动态,后续将更新这里。


    参考资料:

    [1]《The Java Virtual Machine Specification, Java SE 8 Edition》, Oracle. 
    [2]What is the use of Metaspace in Java 8? - StackOverflow 
    [3]About G1 Garbage Collector, Permanent Generation and Metaspace 
    [4]JEP 122: Remove the Permanent Generation 
    [5]PermGen elimination in JDK 8 - StackOverflow

    版权声明:本文为博主原创文章,基于CC-BY-SA 4.0许可(自由转载-非商用-非衍生-保持署名)
     
    转自:http://blog.csdn.net/sczyh22/article/details/46662279
  • 相关阅读:
    2017-09-13
    JavaSE07——异常
    FastDFS入门、搭建以及应用(转载)
    Centos7安装JDK1.8
    「扫盲」 Elasticsearch(转载)
    Java06——面向对象
    Java05——数组
    Java02——基础
    spring boot 配置文件配置项 数字特殊处理问题
    java动态代理机制之自定义实现动态代理
  • 原文地址:https://www.cnblogs.com/shangdongbin/p/7743727.html
Copyright © 2020-2023  润新知