java Tomcat-Spring-Hibernate Web 应用程序中的“PermGen out of space”异常可以做什么?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1124131/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What can be done with 'PermGen out of space' exception in Tomcat-Spring-Hibernate web application?
提问by
We have an web application that uses Spring-Hibernate to persist registered users data in Oracle database. The application works fine in development environment, but when we copy it int live environment with much more data, it failed. Initially the application starts normally, but after few actions 'PermGen out of space' exception occured.
我们有一个 Web 应用程序,它使用 Spring-Hibernate 将注册用户数据保存在 Oracle 数据库中。该应用程序在开发环境中运行良好,但是当我们将其复制到具有更多数据的实时环境中时,它失败了。最初应用程序正常启动,但在几次操作后出现“永久代空间不足”异常。
I've started to search in Google, Spring and Hibernate forums, but it doesn't help. There is many discussions about this error, but for each solution, there are people, that say: 'It works' and other people say 'It doesn't'.
我已经开始在 Google、Spring 和 Hibernate 论坛中搜索,但没有帮助。关于这个错误有很多讨论,但对于每个解决方案,都有人说:“它有效”而其他人说“它没有”。
For example, many people offer to increase -XX:MaxPermSizeJVM parameter, other says that it doesn't works. There are posts that says that the problem in use of javassist library and others and cglib library needed to be used. Others says that the problem is in cglib.
例如,很多人提出增加-XX:MaxPermSizeJVM参数,其他人说它不起作用。有帖子说需要使用javassist库和其他和cglib库的问题。其他人说问题出在 cglib 中。
We use Java1.5_0_09, Spring 2.5 with javaassist3.4.GA, Tomcat 5.5 as web-container and Oracle 10g as database.
我们使用 Java1.5_0_09、带有 javaassist3.4.GA 的 Spring 2.5、Tomcat 5.5 作为 web 容器和 Oracle 10g 作为数据库。
Can anybody explain me what causes this problem and how to solve it?
任何人都可以向我解释是什么导致了这个问题以及如何解决它?
回答by skaffman
The -XX:MaxPermSizedoes work, you've just got to get the right value. The default, I believe, is 32mb for t the client-mode VM, and 64mb for the server mode VM. I suggest setting it to 256mb, if you have the memory:
该-XX:MaxPermSize做的工作,你刚刚得到正确的值。我相信,客户端模式 VM 的默认值是 32mb,服务器模式 VM 的默认值是 64mb。如果您有内存,我建议将其设置为 256mb:
java -XX:MaxPermSize=256m
The problem occurs because Spring and Hibernate can make heavy use of runtime-generated classes, sometimes a lot of them. These generated classes all go into the PermGen memory pool, so if you use those frameworks, you often need to boost your PermGen to large amounts.
出现这个问题是因为 Spring 和 Hibernate 可以大量使用运行时生成的类,有时会使用很多。这些生成的类都进入 PermGen 内存池,因此如果您使用这些框架,您通常需要将 PermGen 提升到大量。
回答by Mercer Traieste
You must be aware that some versions of Tomcat have memory leaks on war redeployment. It happened to me on tomcat 6.0.x.
您必须意识到某些版本的 Tomcat 在重新部署War时会出现内存泄漏。它发生在我的 tomcat 6.0.x 上。
As suggested increase the MaxPermSize, this is a temporary solution for your development machine - and when you get the error, after 2-3 days, just restart the server. On production is not that simple. So this works for development, but this approach doesn't work for production, where you should have the memory leaks issues fixed.
按照建议增加MaxPermSize,这是您的开发机器的临时解决方案 - 当您收到错误时,2-3 天后,只需重新启动服务器。生产上没有那么简单。所以这适用于开发,但这种方法不适用于生产,您应该修复内存泄漏问题。
To discover the leaks use the jconsoleapplication that comes with jdk 1.6 and 1.5. You can bind to a process, and watch memory used over time.
要发现泄漏,请使用jdk 1.6 和 1.5 附带的jconsole应用程序。您可以绑定到一个进程,并观察随着时间的推移使用的内存。
You can also read these:
你也可以阅读这些:
- http://frankkieviet.blogspot.com/2006/10/classloader-leaks-dreaded-permgen-space.html
- http://frankkieviet.blogspot.com/2006/10/how-to-fix-dreaded-permgen-space.html
- http://java.sun.com/developer/technicalArticles/J2SE/monitoring/index.html
- http://my.opera.com/karmazilla/blog/2007/03/13/good-riddance-permgen-outofmemoryerror
- http://my.opera.com/karmazilla/blog/2007/03/15/permgen-strikes-back
- http://frankkieviet.blogspot.com/2006/10/classloader-leaks-dreaded-permgen-space.html
- http://frankkieviet.blogspot.com/2006/10/how-to-fix-dreaded-permgen-space.html
- http://java.sun.com/developer/technicalArticles/J2SE/monitoring/index.html
- http://my.opera.com/karmazilla/blog/2007/03/13/good-riddance-permgen-outofmemoryerror
- http://my.opera.com/karmazilla/blog/2007/03/15/permgen-strikes-back
回答by Matthew Murdoch
I have seen this problem with Hibernate (used without Spring). The issue there was that we were creating an instance of a SessionFactoryfor each user request rather than creating a single instance for the lifetime of the application.
我已经在 Hibernate 中看到了这个问题(在没有 Spring 的情况下使用)。问题在于我们为每个用户请求创建了一个SessionFactory的实例,而不是为应用程序的生命周期创建单个实例。
I used the YourKit profilerto investigate this and discover the issue.
我使用YourKit 分析器对此进行了调查并发现了问题。
回答by Rich Seller
As skaffman says the -XX:MaxPermSize property does work, however sometimes you can have an underlying problem that upping the limit may only defer.
正如 skaffman 所说, -XX:MaxPermSize 属性确实有效,但是有时您可能会遇到潜在问题,即提高限制可能只会推迟。
Have you seen this note? It helped me resolve a similar problem once. To summarise the link:
你看过这个笔记吗?它帮助我解决了一次类似的问题。总结一下链接:
- Put JDBC driver in common/lib (as tomcat documentationsays) and not in WEB-INF/lib
- Don't put commons-logging into WEB-INF/lib since tomcat already bootstraps it
- 将 JDBC 驱动程序放在 common/lib 中(如tomcat 文档所述)而不是 WEB-INF/lib
- 不要将 commons-logging 放入 WEB-INF/lib 中,因为 tomcat 已经引导它了
回答by duffymo
Visual GC, now part of JDK 6, gives a very nice graphical representation of memory in real time. You can see what's happening to eden, generational, and perm spaces. You just won't see why.
Visual GC(现在是 JDK 6 的一部分)提供了非常漂亮的实时内存图形表示。您可以看到 eden、世代和永久空间发生了什么。你只是不会明白为什么。
UPDATE: It's bin/jvisualvm.exe in my JDK 1.6.0_13 distro. Give it the PID of the process you want to monitor.
更新:它是我的 JDK 1.6.0_13 发行版中的 bin/jvisualvm.exe。给它你想要监控的进程的 PID。
回答by duffymo
All responses here relates to PermGen problem that happens because of several restarts of web-app, but in this case the problem already happens on first deployment after tomcat restart, so it can't be the problem of ClassLoader's references or commons-logging.
这里所有的回答都与web-app多次重启导致的PermGen问题有关,但在这种情况下,问题已经发生在tomcat重启后第一次部署时,所以它不可能是ClassLoader的引用或commons-logging的问题。
回答by Michael Wiles
If you're running on jdk6 then you can use the jconsole app to monitor the memory usage of the application and investigate further.
如果您在 jdk6 上运行,那么您可以使用 jconsole 应用程序来监视应用程序的内存使用情况并进一步调查。
Another avenue to pursue is to use a profiler, I use JProfiler, and take a look at the application with that. It will tell you exactly where the problem is coming from.
另一个追求的途径是使用分析器,我使用 JProfiler,然后看一下应用程序。它会告诉您问题的确切来源。
回答by Matyas
I ran in the same problem, and I've read thatTomcat is the culprit in this situation.
我遇到了同样的问题,我读到Tomcat 是这种情况的罪魁祸首。
Then I switched to jetty instead and everything turned out great, and the app deploys/runs as expected. So if tomcat is not a must, then I'd suggest Jetty.
然后我改用了 jetty,结果一切都很好,应用程序按预期部署/运行。所以如果 tomcat 不是必须的,那么我建议使用 Jetty。

