PermGen和Metaspace有什么区别?

2022-08-31 08:30:31

在Java 7之前,JVM内存中有一个名为PermGen的区域,JVM曾经保留其类。在Java 8中,它被移除并被替换为名为Metaspace的区域

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

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


答案 1

从用户的角度来看,主要区别 - 我认为前面的答案没有强调足够 - 是Metaspace默认自动增加其大小(直到底层操作系统提供的大小),而PermGen始终具有固定的最大大小。您可以使用 JVM 参数为 Metaspace 设置固定的最大值,但不能使 PermGen 自动增加。

在很大程度上,这只是名称的更改。当PermGen被引入时,没有Java EE或动态类(un)加载,所以一旦一个类被加载,它就会卡在内存中,直到JVM关闭 - 因此永久生成。如今,类可以在JVM的生命周期内加载和卸载,因此Metaspace对于保存元数据的区域更有意义。

它们都包含实例,并且它们都遭受类加载器泄漏。唯一的区别是,使用Metaspace默认设置,需要更长的时间才能注意到症状(因为它会自动增加尽可能多的症状),即您只是将问题推得更远而没有解决问题。OTOH,我想耗尽操作系统内存的影响可能比仅仅用完JVM PermGen更严重,所以我不确定这是否是一个很大的改进。java.lang.Class

无论你是将 JVM 与 PermGen 还是 Metaspace 一起使用,如果你正在执行动态类卸载,你应该采取措施防止类加载器泄漏,例如使用我的 ClassLoader 泄漏预防库


答案 2

再见,再见彼尔姆根,你好元空间

PermGen已被完全删除。

元空间垃圾回收 - 一旦类元数据使用率达到 .,就会触发失效类和类装入器的垃圾回收。MaxMetaspaceSize

该空间被保留不再与 相邻,现在已经移动到本机内存中称为.MetadataJava heapmetadataMetaspace

简单来说

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

删除并不意味着您的类加载器泄漏问题已经消失。因此,是的,您仍然必须监控您的消耗并相应地进行计划,因为泄漏最终会消耗您的整个本机内存。PermGen

其他一些文章,带有分析:Link1Link2这个


推荐