永久代,方法区 和 元空间之间的关系

永久区(PGS)

JVM内存结构分为 堆,方法区,栈,程序计数器,本地方法区。 这些都是逻辑内存区域划分,实际上不同的
虚拟机的实现方式是不同的,我们常用的也是普及率最高 的虚拟机HotSpot,只有他有永久代这个概念。
  • PGS算是方法区实现,他和堆的内存是连续的一个整体,但是逻辑上是隔离的,所以在垃圾回收的时候,常常说新生代,老年代时,也会说到永久代。
  • PGS主要存储,对象的Class实例和Meta信息,在运行时,不会对PGS进行垃圾回收。
  • 当第一次使用类的静态方法(包括构造方法)时,JVM会将对应的.class文件加载到内存,
    并按照Class对象的方式存储到PGS区域,如果你的应用中有很多CLASS的话,就很可能出现
    java.lang.OutOfMemoryError: PermGen space 错误,
  • 如果你大量的第三方jar, 同时加载的类的数量过多其大小超过了jvm默认的大小(4M)那么就会产生此错误信息了。
  • 在JDK1.6及之前 方法区还包含常量池的概念 1.7之后就将常量池移到堆区了
  • 在1.8之后移除了永久区的说法,取而代之的是元空间
    永久代,方法区 和 元空间之间的关系_第1张图片

为什么会移除永久代

表面上看是为了避免OOM异常。因为通常使用PermSize和MaxPermSize设置永久代的大小就决定了永久代的上限,但是不是总能知道应该设置为多大合适, 如果使用默认值很容易遇到OOM错误。
当使用元空间时,可以加载多少类的元数据就不再由MaxPermSize控制, 而由系统的实际可用空间来控制。
更深层的原因还是要合并HotSpot和JRockit的代码,使用了元空间取代永久代,不用担心运行性能问题了,在覆盖到的测试中, 取代后程序启动和运行速度降低不超过1%,但是这点性能损失换来了更大的安全保障。

元空间(metaspace)

  • 元空间在取代永久代之后,唯一的不同之处在于,元空间所占用的内存为本地内存,不在是JVM申请的内存,所以只要机器还有内存,元空间就可以一直申请使用。由下面的参数可以看出,并没有设置元空间最大内存的参数,就是可以充分利用机器的内存。

元空间的参数配置

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

你可能感兴趣的:(方法区,元空间,JAVA,jvm,java,永久代,元空间,方法区)