大家好,欢迎来到IT知识分享网。
一、永久代
永久代与元空间有千丝万缕的联系,首先来看一下永久代。
永久代更规范的名字的叫做方法区,永久代是方法区的一种实现方式,方法区是java规范中定义的,只有hotspot才有永久代。之所以叫它永久代是因为垃圾回收效果很差,大部分的数据会一直存在直到程序停止运行。
永久代里面一般存储类相关信息,比如类常量、字符串常量、方法代码、类的定义数据等,如果要回收永久代的空间,需要将类卸载,而类卸载的条件非常苛刻,所以空间一般回收很难。当程序中有大量动态生成类时,这些类信息都要存储到永久代,很容易造成方法区溢出。
二、元空间
- Klass 结构,这个非常重要,把它理解为一个 Java 类在虚拟机内部的表示;
- method metadata,包括方法的字节码、局部变量表、异常表、参数信息等;
- 注解;
- 方法计数器,记录方法被执行的次数,用来辅助 JIT 决策;
- 其他
- 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