当前位置: 首页 > 知识库问答 >
问题:

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

韩弘阔
2023-03-14

在Java 7之前,JVM内存中有一个名为PermGen的区域,JVM以前在这里保存它的类。在Java 8中,它被移除并被称为元空间的区域所取代。

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

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

共有3个答案

糜凯泽
2023-03-14

简而言之,如果没有 -XX:MaxMetaspaceSize 的限制,则元空间大小会根据需要在本机内存中自动增加加载类元数据

孔磊
2023-03-14

再见,再见,你好元空间

PermGen已被完全删除。

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

元数据保存的空间不再与 Java 堆相邻,元数据现在已移动到本机内存到称为元空间的区域。

用简单的话来说,

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

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

其他一些文章,有分析:Link1,Link2,还有这个

白才艺
2023-03-14

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

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

它们都包含< code>java.lang.Class实例,并且都存在类加载器泄漏问题。唯一的区别是,使用Metaspace的默认设置,需要更长时间才能注意到症状(因为它会尽可能自动增加),也就是说,您只是将问题推得更远,而没有解决它。OTOH我想耗尽操作系统内存的影响可能比仅仅耗尽JVM PermGen更严重,所以我不确定这是一个很大的改进。

无论你是使用 JVM 与 PermGen 还是 Metaspace,如果你正在执行动态类卸载,你应该采取措施防止类加载器泄漏,例如通过使用我的 ClassLoader 泄漏预防库。

 类似资料:
  • 问题内容: 直到Java 7为止,JVM内存中都有一个称为 PermGen 的区域,JVM用来保留其类。在Java 8中 ,已将其删除并替换为名为 Metaspace 的区域。 什么是 最重要的区别 PermGen的和元空间之间? 我知道的唯一区别是,不再可以抛出该异常,并且忽略了VM参数。 问题答案: 从用户角度来看,主要的区别(我认为先前的答案不够强调)是, 默认情况下 , Metaspace

  • 和之间有什么区别? 是什么原因导致他们被扔?如何解决这些问题? 在修改现有代码以包含新的jar文件时,我经常会遇到这些可抛物。我在通过WebStart发布的一个Java应用程序的客户端和服务器端都碰到了它们。 我遇到的可能原因是: 代码客户端的中未包含的包 我们正在使用的新JAR缺少运行时类路径 版本与以前的JAR冲突 当我今天遇到这些问题时,我会采取跟踪和错误的方法来使事情正常工作。我需要更多的

  • 当我试图在Spring4.x上进行测试时,我使用了MockMvc web客户端,但我正在阅读和尝试Spring5.x的新特性。 我认为,WebTestClient和MockMvc是相同或非常相似的。 MockMvc和WebTestClient之间的区别是什么?

  • 有人能给我解释一下map和flatMap之间的区别,以及什么是各自的好用例吗? “结果扁平化”是什么意思?它有什么好处?

  • 给定以下从静态编程语言Koans中提取的代码: 我自己的解决方案使用了。两者都适用于koan场景。 和的文档似乎非常相似。 这两个功能有什么区别?

  • 问题内容: 在此示例中: 无法编译为: 而被编译器接受。 这个答案说明唯一的区别是,与不同,它允许您稍后引用类型,似乎并非如此。 是什么区别,并在这种情况下,为什么不第一编译? 问题答案: 通过使用以下签名定义方法: 并像这样调用它: 在jls§8.1.2中,我们发现(有趣的部分被我加粗了): 通用类声明定义了一组参数化类型(第4.5节), 每种可能通过类型arguments调用类型参数节的类型