Jetty 7:OutOfMemoryError:应用程序重新部署时的 PermGen 空间

发布于 2024-11-28 02:59:15 字数 308 浏览 3 评论 0原文

应用程序第一次正确启动。然后我删除 webapp/*.war 文件并粘贴新版本的 *.war。 Jetty开始部署新的war,但出现错误java.lang.OutOfMemoryError: PermGen space。如何配置 Jetty 来修复错误/进行正确的重新部署?

这个解决方案对我没有帮助。
Jetty版本:jetty-7.4.3.v20110701

First time app starts correctly. Then I delete webapp/*.war file and paste new version of *.war. Jetty start deploying new war but error java.lang.OutOfMemoryError: PermGen space occurs. How can I configure Jetty to fix error / make correct redeploy?

This solution doesn't help me.
Jetty version: jetty-7.4.3.v20110701

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

萝莉病 2024-12-05 02:59:15

可能没有办法通过配置来解决这个问题。每个 JVM 都有一个 PermGen 内存区域,用于类加载和静态数据。每当您的应用程序被取消部署时,它的类加载器都应该被丢弃,并且它加载的所有类也应该被丢弃。当由于对类加载器的其他引用仍然存在而失败时,垃圾收集类加载器和应用程序类也将失败。

博客条目其后续解释问题的可能根源。每当应用程序容器的代码使用包含对您的某个类的引用的类时,就会阻止对您的类进行垃圾收集。上述博客文章中的示例是 java.util.logging.Level 构造函数:

protected Level(String name, int value) {
    this.name = name;
    this.value = value;
    synchronized (Level.class) {
        known.add(this);
    }
}

请注意,known 是 java.util.logging.Level 的静态成员。构造函数存储对所有创建的实例的引用。因此,一旦 Level 类从应用程序代码中加载或实例化,垃圾收集就无法删除您的类。

为了解决这个问题,您可以避免在您自己的代码之外使用所有类,或者确保在您的代码之外不保留对您的类的引用。这两个问题都可能发生在 Java 提供的任何类中,因此无法在您的应用程序中修复。您无法仅通过更改自己的代码来防止问题发生!

您的选择基本上是:

  • 增加内存限制并减少错误发生的频率
  • 按照链接博客文章中的详细信息分析您的代码,并避免使用存储对对象的引用的类

There is probably no way to configure the problem away. Each JVM has one PermGen memory area that is used for class loading and static data. Whenever your application gets undeployed its classloader should be discarded and all classes loaded by it as well. When this fails because other references to the classloader still exist, garbage collecting the classloader and your applications classes will also fail.

A blog entry and its follow up explain a possible source of the problem. Whenever the application container's code uses a class that holds a reference to one of your classes, garbage collection of your classes is prevented. The example from the mentioned blog entry is the java.util.logging.Level constructor:

protected Level(String name, int value) {
    this.name = name;
    this.value = value;
    synchronized (Level.class) {
        known.add(this);
    }
}

Note that known is a static member of java.util.logging.Level. The constructor stores a reference to all created instances. So as soon as the Level class was loaded or instantiated from outwith your application's code, garbage collection can't remove your classes.

To solve the problem you could avoid all classes that are in use outwith your own code or ensure no references are held to your classes from outwith your code. Both problems could occur within any class delivered with Java and are thus not feasible to be fixed within your application. You cannot prevent the problem by altering only your own code!

Your options are basically:

  • Increasing the memory limits and have the error strike less often
  • Analyze your code as detailed in the linked blog posts and avoid using the classes that store references to your objects
彻夜缠绵 2024-12-05 02:59:15

如果发生 PermGen 内存不足,您需要重新启动 jvm,在您的情况下重新启动 jetty。您可以使用链接解决方案中的 JVM 选项增加 PermGen 空间,以便稍后发生这种情况(我的意思是稍后:在更多重新部署之后)。但这种情况偶尔会发生,你几乎无法避免这种情况。您链接的答案很好地解释了 PermGenSpace 是什么以及它溢出的原因。

使用:

-XX:PermSize=64M -XX:MaxPermSize=128M

或者,如果这还不够的话

-XX:PermSize=256M -XX:MaxPermSize=512M

此外,如果使用此命令,请务必增加虚拟机的可用空间量。

使用

-Xms128M -Xmx256M

If a PermGen out of memory occurs, you need to restart the jvm, in your case restart jetty. You may increase the PermGen space with the JVM options in your linked solution so this happens later (with later I mean: after more redeploys). But it will happen every once in a while and you can do next to nothing to avoid that. The answer you linked explained well what PermGenSpace is and why it overflows.

Use:

-XX:PermSize=64M -XX:MaxPermSize=128M

or, if that was not enough yet

-XX:PermSize=256M -XX:MaxPermSize=512M

Also, be sure to increase the amount of space available to the vm in general if you use this commands.

use

-Xms128M -Xmx256M
深海不蓝 2024-12-05 02:59:15

对于 Jetty 7.6.6 或更高版本,这可能会有所帮助 http://www.eclipse.org/jetty/documentation/current/preventing-memory-leaks.html

我们使用了 AppContextLeakPreventer,它有助于解决由于 permgen 空间而导致的 OOM 错误

For Jetty 7.6.6 or later this may help http://www.eclipse.org/jetty/documentation/current/preventing-memory-leaks.html.

We used the AppContextLeakPreventer and it helped with the OOM errors due to permgen space

酒几许 2024-12-05 02:59:15

我在使用 HotSpot 时也遇到了同样的问题,但是使用没有永久代的 JRockit,问题就消失了。它现在是免费的,所以您可能想尝试一下:https://blogs.oracle.com/henrik /entry/jrockit_is_now_free_and

I have this same problem with HotSpot, but with JRockit, which doesn't have a Permanent Generation, the problem has gone away. It's free now, so you might want to try it: https://blogs.oracle.com/henrik/entry/jrockit_is_now_free_and

入画浅相思 2024-12-05 02:59:15

看起来非常像永久代泄漏。每当您的应用程序在取消部署后留下一些类闲置时,您就会遇到此问题。你可以尝试最新版本的Plumbr,也许它会找到剩下的类。

Looks very much like Permanent Generation leak. Whenever your application left some classes to hang around after it is undeployed, you get this problem. You can try the latest version of Plumbr, may be it will find the left-over classes.

嘿哥们儿 2024-12-05 02:59:15

对于未来的读者(相对于提出这个问题时):

JDK 8中,永久代空间已经消失(不再存在)。相反,现在有从机器的本机空间获取的元空间。

如果您遇到 Perm Gen 溢出问题,那么您可能需要查看 这个解释此评论关于删除过程

For Readers of the Future (relative to when this question has been asked):

In JDK 8 the Perm Gen Space is gone (not there anymore). Instead there is now Metaspace which is taken from the native space of the machine.

If you had problems of Perm Gen Overflow then you might want to have a look into this explanation and this comments on the removal process.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文