java8之元空间(Metaspace)

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

大家好,欢迎来到IT知识分享网。

一、永久代

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

二、元空间

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

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/153136.html

(0)
上一篇 2025-03-05 20:10
下一篇 2025-03-05 20:15

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信