虚拟机为什么使用元空间替换了永久代

虚拟机为什么使用元空间替换了永久代

        • 方法区
        • 永久代
        • 元空间
        • 为什么使用元空间替换了永久代?

什么是元空间?什么是永久代?为什么用元空间代替永久代?
我们先回顾一下

方法区

方法区和堆一样,是各个线程共享的内存区域,它用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译后的代码等数据。

虚拟机为什么使用元空间替换了永久代_第1张图片
永久代

它和方法区有什么关系呢?
如果在HotSpot虚拟机上开发、部署,很多程序员都把方法区称作永久代。可以说方法区是规范,永久代是Hotspot针对该规范进行的实现。在Java7及以前的版本,方法区都是永久代实现的。

元空间

它和方法区有什么关系呢?
对于Java8,HotSpots取消了永久代,取而代之的是元空间(Metaspace)。换句话说,就是方法区还是在的,只是实现变了,从永久代变为元空间了。

为什么使用元空间替换了永久代?

永久代的方法区,和堆使用的物理内存是连续的。

虚拟机为什么使用元空间替换了永久代_第2张图片

永久代是通过以下这两个参数配置大小的~

  • -XX:PremSize:设置永久代的初始大小
  • -XX:MaxPermSize: 设置永久代的最大值,默认是64M

对于永久代,如果动态生成很多class的话,就很可能出现「java.lang.OutOfMemoryError: PermGen space错误」,因为永久代空间配置有限嘛。最典型的场景是,在web开发比较多jsp页面的时候。

JDK8之后,方法区存在于元空间(Metaspace)。物理内存不再与堆连续,而是直接存在于本地内存中,理论上机器内存有多大,元空间就有多大。

虚拟机为什么使用元空间替换了永久代_第3张图片

可以通过以下的参数来设置元空间的大小:

  • -XX:MetaspaceSize,初始空间大小,达到该值就会触发垃圾收集进行类型卸载,同时GC会对该值进行调整:如果释放了大量的空间,就适当降低该值;如果释放了很少的空间,那么在不超过MaxMetaspaceSize时,适当提高该值。
  • -XX:MaxMetaspaceSize,最大空间,默认是没有限制的。
  • -XX:MinMetaspaceFreeRatio,在GC之后,最小的Metaspace剩余空间容量的百分比,减少为分配空间所导致的垃圾收集
  • -XX:MaxMetaspaceFreeRatio,在GC之后,最大的Metaspace剩余空间容量的百分比,减少为释放空间所导致的垃圾收集

所以,为什么使用元空间替换永久代

表面上看是为了避免OOM异常。因为通常使用PermSize和MaxPermSize设置永久代的大小就决定了永久代的上限,但是不是总能知道应该设置为多大合适, 如果使用默认值很容易遇到OOM错误。当使用元空间时,可以加载多少类的元数据就不再由MaxPermSize控制, 而由系统的实际可用空间来控制。

你可能感兴趣的:(jvm,元空间)