7

我在 Sun 的 JRE6 中运行 Tomcat6 并且每对部署我都会得到 OutOfMemoryException: PermGen。我已经完成了 PermGen 解决方案的谷歌搜索并尝试了许多修复。没有工作。我读了很多关于 Oracle 的 JRockit 的好东西,以及它的 PermGen 分配的大小如何(与 Sun 的 128M 相比),虽然它不能解决问题,但它允许我在 PermGen 异常之间重新部署 100 次,而不是 2现在几次。

JRockit 的问题是在生产中使用它需要花费数千美元购买 WebLogic。存在哪些其他(免费)选项对 PermGen 扩展更宽容?以下 JVM 在这方面的表现如何?

  • IBM JVM
  • 打开 JDK
  • 停电
  • 咖啡

...其他?

更新:有人问我为什么认为 PermGen max 是 128M。原因是每当我尝试将其提高到 128M 以上时,我的 JVM 都无法初始化:

[2009-06-18 01:39:44] [info] Error occurred during initialization of VM [2009-06-18 01:39:44] [info] Could not reserve enough space for object heap [2009-06-18 01:39:44] [395 javajni.c] [error] CreateJavaVM Failed

奇怪的是,它未能为对象heap保留空间,尽管我不确定它是“the” heap 而不是“a” heap。

我以 1024MB 初始和 1536MB 最大堆启动 JVM。

我将关闭这个问题,因为它已被回答,即。“切换是无用的”,而是问为什么我的 Sun JVM 会因较大的 PermGen 设置而失败?

4

7 回答 7

7

我同意 Michael Borgwardt 的观点,即您可以增加 PermGen 的大小,但我不同意这主要是由于内存泄漏。PermGen 空间被大量使用反射的应用程序占用。所以基本上,如果你有一个在 Tomcat 中运行的 Spring/Hibernate 应用程序,请准备好大幅增加 PermGen 空间。

于 2009-06-17T19:56:32.857 回答
5

是什么让您认为 Sun 的 JVM 仅限于 128M PermGen?您可以使用 -XX:MaxPermSize 命令行选项自由设置;默认为 64M。

但是,问题的真正原因可能是应用程序中的内存泄漏,它阻止了类被垃圾收集;这些可能非常微妙,尤其是在涉及 ClassLoader 时,因为它所需要的只是对任何地方的任何类的单个引用。本文详细描述了该问题,并提出了解决该问题的方法。

于 2009-06-17T19:35:14.130 回答
3

从技术上讲,“PermGen”内存池是 Sun JVM 的东西。其他 JVM 不这么称呼它,但它们都有一个或多个非堆内存池的想法。

但是,如果您的 Sun JVM 中的 permgen 存在问题,那么迁移到另一个 JVM 不太可能解决任何问题,它只会以不同的名称表现出来。

如果多次重新部署导致您的问题,只需将 VM 的 PermGen 提高到较大的值。由于这个问题,我们不久前尝试了 JRockit,它遭受了同样的重新部署耗尽。我们回到了 SUn JVM。

于 2009-06-17T19:44:33.533 回答
3

改变 JVM 不是灵丹妙药。您可能会遇到新的意外问题(例如,请参阅有关在 4 个不同 JVM 下启动应用程序的文章)。

  • 您可能会在重新部署时经常发生类泄漏(例如通过类加载器)。坦率地说,我从未见过在 Tomcat 上进行热重新部署(希望有一天能看到)。
  • 您可能有不正确的 JVM 参数(例如,对于 Sun JDK 6 64 位 -XX:+UseParNewGC 开关会导致 PermGen 内存段泄漏。如果添加其他开关:-XX:+UseConcMarkSweepGC -XX:+CMSClassUnloadingEnabled-XX:+CMSPermGenSweepingEnabled情况将得到解决。有趣,但我从未遇到过上面提到的 Sun JDK 6 32 位泄漏)。链接到文章“为生产部署调整 JVM 垃圾收集”。
  • 您的 PermGen 块可能不足以加载类和相关信息(实际上最常发生在 Tomcat 下重新部署后,旧类留在内存中,新类正在加载)

根据我过去的经验,调试这种泄漏是我经历过的最棘手的调试之一。

[更新]

有用的文章如何在应用程序重新部署时消除类加载器链接。

于 2009-06-17T20:25:27.540 回答
0

IBM JVM没有(在 2009 年也没有)有 permgen 。您可以阅读有关它的Generational Concurrent Garbage Collector的更多信息,它是 Java 7 的默认 GC。

我有时专门在 IBM JVM 上运行 Eclipse IDE,因为使用我最喜欢的插件时,它经常会填满 HotSpot JVM 的 permgen。当然,可能存在应该有人修复的内存泄漏,但同时我的 IDE 没有崩溃,我也没有忙于尝试不同的设置。

于 2014-03-10T15:37:47.037 回答
0

Perm gen 可能是最容易处理的内存,我怀疑各种 vm 实现之间会有很大差异。

确保所有在生产中标记为关闭的 Tomcat 配置在生产中都已关闭。

是的,一些框架确实会生成大量类,但它们应该自己清理,而且,无论如何,您可以在 128Mb 中容纳多个类。

说真的,如果 perm gen 继续上升,那么这就是一个应该修复的泄漏,尽管它可能不是你要修复的问题。

于 2009-06-18T05:33:36.713 回答
0

我使用 JRockit,如果我不增加(通过 -XX:MaxPermSize)内存,我仍然会收到 PermGen 错误。我也无法避免得到这个(除了增加它)。

于 2009-06-17T19:56:18.037 回答