PermGen和Metaspace有什么区别?

时间:2014-11-25 15:52:35

标签: java java-8 java-7 permgen metaspace

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

PermGen和Metaspace之间最重要的差异是什么?

我知道的唯一区别是无法再抛出java.lang.OutOfMemoryError: PermGen space并忽略VM参数MaxPermSize

5 个答案:

答案 0 :(得分:120)

与用户观点的主要区别 - 我认为之前的答案不够紧张 - 是默认情况下,Metaspace会自动增加其大小(直到底层操作系统提供的内容),而PermGen始终具有固定的最大尺寸。您可以使用JVM参数为Metaspace设置固定的最大值,但不能使PermGen自动增加。

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

它们都包含java.lang.Class个实例,并且都受到ClassLoader leaks的影响。唯一不同的是,对于Metaspace默认设置,它需要更长的时间,直到您注意到症状(因为它会尽可能多地自动增加),即您只是将问题推得更远而不解决它。 OTOH我想象用完内存操作系统内存的效果可能比仅运行JVM PermGen更严重,所以我不确定它是否有很大的改进。

无论您是使用带有PermGen的JVM还是使用Metaspace,如果您正在进行动态类卸载,您应该对类加载器泄漏采取措施,例如使用我的ClassLoader Leak Prevention library

答案 1 :(得分:33)

再见,Bye PermGen,Hello Metaspace

PermGen 已完全删除。

元数据空间垃圾收集 - 一旦类元数据使用量达到MaxMetaspaceSize,就会触发死类和类加载器的垃圾收集。

Metadata空间Java heap不再与metadata连续,Metaspace现已移至本地记忆中的OOM errors区域。

简单的话

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

删除{{1}}并不意味着您的类加载器泄漏问题已经消失。所以,是的,您仍然需要监控您的消费并相应地进行计划,因为泄漏会最终消耗您的整个本机内存。

其他一些文章,包含分析:Link1Link2this

答案 2 :(得分:9)

简而言之,如果不受rname

限制,则加载类元数据所需的元数据空间大小会自动增加本机内存

答案 3 :(得分:1)

永久代

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

元空间

  • 元空间是一个新的内存空间。
  • 它已经取代了旧的 PermGen 内存空间。
  • 它现在可以处理内存分配。
  • 元空间默认自动增长。

答案 4 :(得分:0)

为了简单起见。

什么是永久代: PermGen 是与主内存堆分开的特殊堆空间。类元数据在此处加载。 java 7 : PermGen 是 JVM 跟踪已加载类的元数据的空间。
java 8 : PermGen 被 Metaspace 取代,具有根据加载类元数据的要求自动增加本机内存的能力。