PermGen和Metaspace有什么区别?


118

直到Java 7为止,JVM内存中都有一个称为PermGen的区域,JVM用来保留其类。在Java 8中,已将其删除并替换为名为Metaspace的区域。

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

我知道的唯一区别是,java.lang.OutOfMemoryError: PermGen space不再可以抛出该异常,并且MaxPermSize忽略了VM参数。



@ the8472是的,但是这个(以及许多其他)谷歌结果仅描述了元空间机制,没有提及任何与此PermGen之间的确切区别的东西。
花王

Answers:


137

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

在很大程度上,这只是名称的更改。早在引入PermGen时,就没有Java EE或动态类的加载(卸载),因此一旦加载了类,它就一直停留在内存中,直到JVM关闭为止,从而实现了永久生成。如今,可以在JVM的生命周期内加载和卸载类,因此对于保留元数据的区域,Metaspace更有意义。

它们都包含java.lang.Class实例,并且都遭受ClassLoader泄漏。唯一的区别是,使用Metaspace默认设置时,它会花费更长的时间,直到您注意到症状为止(因为它会自动增加很多),即,您只是将问题推得更远而没有解决。OTOH我想用完操作系统内存会比只用完JVM PermGen更严重。因此,我不确定这样做是否有很大的改进。

无论您是将JVM与PermGen一起使用,还是与Metaspace一起使用,如果要进行动态类卸载,都应采取措施防止类加载器泄漏,例如,使用我的ClassLoader Leak Prevention库


17
Permgen或Metaspace都不包含类Class的实例。它们仅保留有关已加载类的元信息。类Class的实例与其他类的实例一样,保存在常规堆中。
平均乔

不错的比较。谢谢
Sandeep

1
顺便说一句,OTOH的意思是“另一方面”
sofs1

43

再见,再见PermGen,Hello Metaspace

PermGen已被完全删除。

元空间垃圾回收 -当类元数据使用量达到时,将触发死类和类加载器的垃圾回收MaxMetaspaceSize

Metadata保留的空间不再与相邻Java heapmetadata现在已移至本机内存中的区域称为Metaspace

简单来说

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

的删除PermGen并不意味着您的类加载器泄漏问题已经解决。因此,是的,您仍然必须监视您的使用情况并做出相应的计划,因为泄漏最终将占用您的整个本机内存。

其他一些带有分析的文章:Link1Link2this


6
您可以使用MaxMetaspaceSize而不是MaxPermGen,因此没有理由使用更多或更少的内存或控制更少。
彼得·劳瑞

2
我们在这里谈论什么记忆?RAM内存或HDD内存。
Dinesh

1
@Dinesh RAM(内部存储器)
Aditya Gupta

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.