PermGen和Metaspace有什么区别?

133

在Java 7之前,JVM内存中有一个称为PermGen的区域,JVM用于保存其类。在Java 8中,它被删除并替换为称为Metaspace的区域。

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

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


Java PERMGEN已移除。 - the8472
1
@the8472 是的,但是(包括很多其他)谷歌搜索结果只描述了Metaspace机制,并未提到与PermGen之间的确切差异。 - Kao
5个回答

158
元空间相较于永久代最主要的用户体验区别在于,默认情况下元空间会自动增加其大小(最多达到底层操作系统所提供的大小),而永久代始终具有固定的最大大小。您可以使用JVM参数设置元空间的固定最大值,但无法使永久代自动增加。
在很大程度上,这只是一种名称变更。当永久代被引入时,还没有Java EE或动态类(反)加载,因此一旦类被加载,它就会一直停留在内存中,直到JVM关闭 - 因此称为永久代。如今,在JVM生命周期内可能会加载和卸载类,因此Metaspace对于保存元数据的区域更有意义。
它们都包含java.lang.Class实例,并且它们两者都受到ClassLoader泄漏的影响。唯一的区别在于,使用Metaspace默认设置时,需要更长的时间才能注意到这些症状(因为它会尽可能地自动增加),即您只是将问题推迟了而没有解决它。但另一方面,我想当操作系统内存不足时的影响可能比仅仅是运行出JVM PermGen更严重,因此我不确定这是否是实质性的改进。
无论您是使用具有PermGen还是Metaspace的JVM,如果正在进行动态类卸载,则应采取措施防止ClassLoader泄漏,例如使用我的ClassLoader Leak Prevention库

27
Permgen和Metaspace都不包含类Class的实例,它们只保存有关已加载类的元信息。类Class的实例与其他类的实例一样存储在常规堆中。 - Average Joe
很好的比较。谢谢。 - Sandeep
4
顺便提一下,OTOH 的意思是 “另一方面”。 - sofs1
顺便说一句,“btw” 的意思是“顺便说一下”。 - Ricardo
这里没有Java EE或动态类(不)加载。是否有官方文件描述这个问题? - HelloWorld

51

再见,PermGen,你好,Metaspace

PermGen已经完全删除。

Metaspace垃圾回收——当类元数据的使用量达到MaxMetaspaceSize时,死亡类和类加载器的垃圾回收就会被触发。

以前存储Metadata的空间不再与Java heap相连续,现在metadata已经移到了本地内存中的一个区域,称为Metaspace

简单来说,

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

删除PermGen并不意味着您的类装入器泄漏问题已经解决。因此,是的,您仍需要监视您的消耗并进行相应的计划,因为泄漏会导致消耗整个本地内存。

一些其他文章,带有分析:Link1Link2,以及此链接


6
现在使用的是MaxMetaspaceSize而不是MaxPermGen,因此它使用的内存量不会更多或更少,你也不会失去任何控制。请注意,这并没有改变原意。 - Peter Lawrey
2
我们在谈论哪种内存?是RAM内存还是HDD内存。 - Dinesh
1
@Dinesh RAM(内存) - YetAnotherBot
OOM => "内存不足" - shubh gaikwad

14
简而言之,如果未使用-XX:MaxMetaspaceSize限制,Metaspace大小会自动增大以满足加载类元数据所需的本机内存。

3

PermGen

  • (永久代)是一个与主内存空间分离的特殊堆空间。
  • JVM在PermGen中跟踪类元数据,也会将所有静态内容存储在其中。
  • 由于内存大小受限,PermGen可能会抛出OutOfMemoryError。

Metaspace

  • Metaspace是一个新的内存空间。
  • 它已经替换了旧的PermGen内存空间。
  • 它现在可以处理内存分配。
  • 默认情况下,Metaspace会自动增长。

2

让我们简单来解释一下。

什么是 PermGen : PermGen 是一个特殊的堆空间,与主内存堆分开。类元数据被加载到这里。 Java 7 :PermGen 是 JVM 跟踪已加载类的元数据的空间。
Java 8 :PermGen 被 Metaspace 取代,具有自动增加本地内存的能力,以满足加载类元数据的需求。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接