java8之元空间(Metaspace)

java里面垃圾回收效果最差的是永久代,而且永久代溢出也是一个非常常见的问题,从java7开始,原来存储于永久代的数据就不断的被移到其他位置,有不少数据都移动到了堆区,比如字符串常量池挪到了堆区,在java8最终将永久代移除,另外新增了一个区,也就是元空间(Metaspace),元空间承接了部分永久代的数据。本文接下来介绍元空间。

一、永久代

永久代与元空间有千丝万缕的联系,首先来看一下永久代。
永久代更规范的名字的叫做方法区,永久代是方法区的一种实现方式,方法区是java规范中定义的,只有hotspot才有永久代。之所以叫它永久代是因为垃圾回收效果很差,大部分的数据会一直存在直到程序停止运行。
永久代里面一般存储类相关信息,比如类常量、字符串常量、方法代码、类的定义数据等,如果要回收永久代的空间,需要将类卸载,而类卸载的条件非常苛刻,所以空间一般回收很难。当程序中有大量动态生成类时,这些类信息都要存储到永久代,很容易造成方法区溢出。

二、元空间

在java8里面,元空间替代了永久代,原来存放于永久代的类信息现在放到了元空间,我们再也不会看到PermGen error的异常了,本质上来说,元空间也是方法区的一种实现。
元空间是用来存放class metadata的,class metadata用于记录一个Java 类在JVM中的信息,包括但不限于JVM class file format的运行时数据:

  1. Klass 结构,这个非常重要,把它理解为一个 Java 类在虚拟机内部的表示;
  2. method metadata,包括方法的字节码、局部变量表、异常表、参数信息等;
  3. 注解;
  4. 方法计数器,记录方法被执行的次数,用来辅助 JIT 决策;
  5. 其他

虽然每个 Java 类都关联了一个 java.lang.Class的实例,而且它是一个贮存在堆中的 Java 对象。但是类的class metadata不是一个Java对象,它不在堆中,而是在元空间中。
方法区和元空间最大区别是:元空间并不在虚拟机中,而是使用本地内存。因此,默认情况下,元空间的大小仅受本地内存限制,但可以通过以下参数来指定元空间的大小:

  • XX:MetaspaceSize,初始空间大小,达到该值就会触发垃圾收集进行类型卸载,同时GC会对该值进行调整:如果释放了大量的空间,就适当降低该值;如果释放了很少的空间,那么在不超过MaxMetaspaceSize时,适当提高该值。
  • XX:MaxMetaspaceSize,最大空间,默认是没有限制的,也就是说内存有多大,元空间就由多大。

除了上面两个指定大小的选项以外,还有两个与 GC 相关的属性:

  • XX:MinMetaspaceFreeRatio,当进行过Metaspace
    GC之后,会计算当前Metaspace的空闲空间比,如果空闲比小于这个参数,那么虚拟机将增长Metaspace的大小。设置该参数可以控制Metaspace的增长的速度,太小的值会导致Metaspace增长的缓慢,Metaspace的使用逐渐趋于饱和,可能会影响之后类的加载。而太大的值会导致Metaspace增长的过快,浪费内存。
  • XX:MaxMetaspaceFreeRatio,当进行过Metaspace GC之后,
    会计算当前Metaspace的空闲空间比,如果空闲比大于这个参数,那么虚拟机会释放Metaspace的部分空间。在本机该参数的默认值为70,也就是70%。
  • XX:MaxMetaspaceExpansion:Metaspace增长时的最大幅度。
  • XX:MinMetaspaceExpansion:Metaspace增长时的最小幅度。

尽管没有了PermGen error异常,但是因为类的信息存放在元空间,所以如果元空间设置的过小,而系统需要加载很多类,那么还是会造成元空间内存溢出,比如会报如下异常:

Caused by: java.lang.OutOfMemoryError: Metaspace

元空间是按照类加载器分配空间的,也就是说类加载器加载了一个类,元空间分配给这个类的空间其实是分配给的类加载器,不同的类加载器占用不同的空间,它们之间不共享类信息,如果程序中有大量的类加载器,而它们加载的类非常少,那么有可能会造成大量的空间浪费,而且还有可能造成java频繁GC而无法回收内存的现象。如果发现类加载器已经失效了,java可以直接将该类加载器对应的空间整体回收,不过类加载器一直存活的话,该类加载器加载的类所占据的空间不会被回收。

Java8内存模型—永久代(PermGen)和元空间(Metaspace)
Java8 Metaspace调优
深入理解堆外内存 Metaspace

  • 1
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值