Java1.8开始为什么用元空间替换永久代

一 概述

Java1.8开始,JDK中的永久代被元空间替换了。

二 回顾JMM中的方法区

Java1.8开始为什么用元空间替换永久代_第1张图片

如图所示,方法区同堆空间一样,属于所有线程共享的数据区域,它用于存储已经被虚拟机加载的类信息,常量,静态变量,即时编译后的代码等数据。

三 回顾永久代与方法区的关系

如果在HotSpot虚拟机上开发,部署,方法区是规范,永久代是Hotspot针对该规范进行的实现。在Java7及以前的版本中,方法区都是永久代实现的。

四 元空间与方法区的关系

对于Java8而言,HotSpots取消了永久代,取而代之的是元空间(Metaspace),换言之,就是方法区是在的,只是实现方式由原来的永久代变成了现在的元空间了。

多版本JDK中的参数信息

五 使用元空间替换永久代的原因

Java1.8开始为什么用元空间替换永久代_第2张图片

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

永久代的大小配置

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

对于永久代,如果动态生成很多class的时候,很有可能出现java.lang.OutOfMemoryError:PermGen space错误,这是因为永久代空间配置的大小有限。

在典型的单一应用中,需要编写和加载很多的jsp页面,就会出现java.lang.OutOfMemoryError。

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

Java1.8开始为什么用元空间替换永久代_第3张图片

基于上图可知,元空间存在于本地内存中,我们可以通过一些参数对元空间的大小进行配置:

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

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

你可能感兴趣的:(JVM,Java,元空间,永久代)