PermGen和Metaspace有什么区别?
在Java 7之前,JVM内存中有一个名为PermGen的区域,JVM用于保留其类。 在Java 8中,它被删除并被称为Metaspace的区域所取代。
PermGen和Metaspace最重要的区别是什么?
唯一的区别是我知道java.lang.OutOfMemoryError: PermGen space
不能再被抛出,VM参数MaxPermSize
被忽略。
与用户角度的主要区别 - 我认为以前的答案没有足够强调 - 是默认情况下 , Metaspace会自动增加其大小(直到底层操作系统提供的内容),而PermGen始终具有固定的最大大小。 您可以使用JVM参数为Metaspace设置固定的最大值,但不能使PermGen自动增加。
在很大程度上,这只是名称的改变。 当引入PermGen时,没有Java EE或动态类(un)加载,所以一旦加载了一个类,它就会一直滞留在内存中,直到JVM关闭 - 从而永久生成。 现在类可以在JVM的生命周期中被加载和卸载,所以Metaspace对元数据保存的区域更有意义。
它们都包含java.lang.Class
实例,它们都受到ClassLoader泄漏的影响。 唯一不同的是,使用Metaspace的默认设置,需要更长的时间直到您注意到症状(因为它会自动增加尽可能多的),也就是说,您只是将问题推得更远,而不解决问题。 OTOH我认为耗尽操作系统内存的效果可能会比使用JVM PermGen更加严重,所以我不确定它有多大的改进。
无论您是使用PermGen还是Metaspace使用JVM,如果您正在执行动态类卸载,则应该采取措施应对类加载器泄漏,例如使用我的ClassLoader泄漏预防库。
Bye,Bye PermGen,Hello Metaspace
PermGen已被完全删除。
元空间垃圾收集 - 一旦类元数据使用量达到MaxMetaspaceSize
就会触发死类和类加载器的垃圾收集。
Metadata
被保存的空间不再与Java heap
相邻, metadata
现在已经移动到本地内存到一个称为Metaspace
的区域。
简而言之 ,
由于类元数据是从本机内存分配的,所以最大可用空间是可用系统内存总量。 因此,您将不再遇到OOM errors
,并最终可能流入交换空间。
删除PermGen
并不意味着你的类加载器泄漏问题已经消失。 所以,是的,你仍然需要监控你的消费并进行相应的计划,因为泄漏最终会消耗你的整个本地内存。
一些其他文章,分析:Link1,Link2和这个
简而言之,根据需要加载类元数据时,Metaspace大小在本机内存中增加,如果不受-XX:MaxMetaspaceSize
限制-XX:MaxMetaspaceSize