在Java7之前,JVM内存中有一个叫做PermGen的区域,JVM用来保存它的类。在Java 8中,它被移除,取而代之的是名为Metaspace的区域。
和PermGen之间最重要的区别是什么?
我所知道的唯一区别是不能再抛出java.lang.OutOfMemoryError: PermGen space
,并且忽略了VM参数MaxPermSize
。
发布于 2014-11-26 16:12:12
从用户的角度来看,主要的区别--我认为前面的答案没有强调--是Metaspace默认自动增加的大小(直到底层操作系统提供的大小),而PermGen总是有一个固定的最大大小。您可以使用JVM参数为Metaspace设置固定的最大值,但不能自动增加PermGen。
在很大程度上,这只是一个名字的改变。回到引入PermGen的时候,没有Java或动态类(Un)加载,所以一旦加载了类,它就会被卡在内存中,直到JVM关闭-因此是永久生成。如今,类可以在JVM的生命周期内加载和卸载,因此Metaspace对于保存元数据的区域更有意义。
它们都包含java.lang.Class
实例,并且都受到ClassLoader leaks的影响。唯一的区别是,使用Metaspace的默认设置,你需要更长的时间才能注意到症状(因为它会尽可能地自动增加),也就是说,你只是把问题推得更远,而没有解决它。我想OS内存耗尽的影响可能比JVM PermGen耗尽的影响更严重,所以我不确定这是不是一个很大的改善。
无论您是将JVM与PermGen一起使用还是与Metaspace一起使用,如果您正在进行动态类卸载,则应该采取措施防止类加载器泄漏,例如使用my ClassLoader Leak Prevention library。
发布于 2014-11-26 00:00:38
再见,再见PermGen,你好
PermGen已完全删除。
元数据垃圾收集-一旦类元数据使用量达到MaxMetaspaceSize
,就会触发对死类和类加载器的垃圾收集。
Metadata
所占用的空间不再与Java heap
相邻,metadata
现在已移到本机内存中的Metaspace
区域。
简而言之,,,
由于类元数据是从本机内存中分配出来的,因此最大可用空间是总的可用系统内存。因此,您将不再遇到OOM errors
,最终可能会溢出到交换空间中。
移除PermGen
并不意味着您的类加载器泄漏问题已经消失。因此,是的,您仍然必须监控您的消耗并相应地进行计划,因为泄漏将最终消耗您的整个本机内存。
发布于 2016-05-29 12:53:48
简而言之,如果不使用-XX:MaxMetaspaceSize
限制,元空间大小会根据加载类元数据的需要自动增加本机内存中的大小
https://stackoverflow.com/questions/27131165
复制相似问题