PermGen和Metaspace有什么不同?

在Java 7之前,JVM内存中有一个名为PermGen的区域,JVM用来保存类。 在Java 8中,它被移除并被称为Metaspace的区域所取代。

PermGen和Metaspace最重要的区别是什么?

唯一的区别是我知道java.lang.OutOfMemoryError: PermGen space不能再被抛出,并且VM参数MaxPermSize被忽略。

与用户angular度的主要区别 – 我认为以前的答案没有足够的重点 – 默认情况下Metaspace会自动增加它的大小(直到底层操作系统提供的),而PermGen总是有一个固定的最大大小。 您可以使用JVM参数为Metaspace设置固定的最大值,但不能使PermGen自动增加。

在很大程度上,这只是名称的改变。 当引入PermGen时,没有加载Java EE或dynamic类(un),所以一旦加载了一个类,它将一直滞留在内存中,直到JVMclosures – 永久代( Permanent Generation)。 现在的类可以在JVM的生命周期中被加载和卸载,所以Metaspace对元数据保存的区域更有意义。

它们都包含java.lang.Class实例,它们都受到ClassLoader泄漏的影响 。 唯一不同的是,使用Metaspace的默认设置,需要更长的时间,直到您注意到症状(因为它会自动增加尽可能多的),也就是说,只是将问题推得更远,而不解决问题。 OTOH我想,操作系统内存耗尽的效果可能会比使用JVM PermGen更加严重,所以我不确定它有多大的改进。

无论你是在PermGen还是Metaspace中使用JVM,如果你正在做dynamic类卸载,你应该采取措施防止类加载器泄漏,例如使用我的ClassLoader泄漏预防库 。

再见,PermGen,你好Metaspace

PermGen已被彻底删除。

元空间垃圾收集 – 当类元数据使用量达到MaxMetaspaceSize会触发死类和类加载器的垃圾收集。

Metadata被保存的空间不再与Java heap相邻, metadata现在已经移动到本地内存到被称为Metaspace的区域。

简而言之

由于类元数据是从本机内存中分配的,所以最大可用空间是可用的系统总内存量。 因此,您将不再遇到OOM errors并可能会溢出到交换空间。

删除PermGen并不意味着你的类加载器泄漏问题已经消失。 所以,是的,你将仍然需要监视你的消费和相应的计划,因为泄漏最终会消耗你的整个本地内存。

一些其他的文章,分析: Link1 , Link2和这个

简而言之,根据需要加载类元数据时,本地内存中的元数据空间大小自动增加(如果不受-XX:MaxMetaspaceSize限制) -XX:MaxMetaspaceSize