“PermGen 空间不足”可以做什么? Tomcat-Spring-Hibernate Web 应用程序中的异常?
我们有一个 Web 应用程序,它使用 Spring-Hibernate 将注册用户数据保存在 Oracle 数据库中。 该应用程序在开发环境中运行良好,但是当我们将其复制到具有更多数据的实时环境中时,它失败了。 最初,应用程序正常启动,但经过几次操作后,出现“PermGen out of space”异常。
我已经开始在 Google、Spring 和 Hibernate 论坛中搜索,但没有帮助。 关于这个错误有很多讨论,但对于每个解决方案,都有人说:“它有效”,而其他人则说“它不起作用”。
例如,很多人提出增加 -XX:MaxPermSize
JVM 参数,其他人说这不起作用。 有帖子说使用javassist库和其他库以及需要使用cglib库时出现问题。 还有人说问题出在cglib上。
我们使用 Java1.5_0_09、Spring 2.5 和 javaassist3.4.GA、Tomcat 5.5 作为 Web 容器,Oracle 10g 作为数据库。
谁能解释一下是什么原因导致了这个问题以及如何解决它?
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.
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'.
For example, many people offer to increase -XX:MaxPermSize
JVM 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.
We use Java1.5_0_09, Spring 2.5 with javaassist3.4.GA, Tomcat 5.5 as web-container and Oracle 10g as database.
Can anybody explain me what causes this problem and how to solve it?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
您必须注意,某些版本的 Tomcat 在战争重新部署时存在内存泄漏。 我在 tomcat 6.0.x 上发生过这种情况。
正如建议增加 MaxPermSize 一样,这是您的开发计算机的临时解决方案 - 当您在 2-3 天后收到错误时,只需重新启动服务器即可。 生产上没那么简单。 因此,这种方法适用于开发,但这种方法不适用于生产,您应该修复内存泄漏问题。
要发现泄漏,请使用 jdk 1.6 和 1.5 附带的 jconsole 应用程序。 您可以绑定到进程,并观察一段时间内使用的内存。
您还可以阅读这些:
You must be aware that some versions of Tomcat have memory leaks on war redeployment. It happened to me on 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.
To discover the leaks use the jconsole application that comes with jdk 1.6 and 1.5. You can bind to a process, and watch memory used over time.
You can also read these:
我在 Hibernate 中看到了这个问题(不使用 Spring)。 问题是我们正在创建 SessionFactory< 的实例/a> 为每个用户请求而不是在应用程序的生命周期内创建单个实例。
我使用 YourKit 分析器 来调查并发现问题。
I have seen this problem with Hibernate (used without Spring). The issue there was that we were creating an instance of a SessionFactory for each user request rather than creating a single instance for the lifetime of the application.
I used the YourKit profiler to investigate this and discover the issue.
正如 skaffman 所说,-XX:MaxPermSize 属性确实有效,但有时您可能会遇到一个潜在的问题,即提高限制可能只会推迟。
您看过此说明吗? 它曾经帮助我解决过类似的问题。
总结链接:
As skaffman says the -XX:MaxPermSize property does work, however sometimes you can have an underlying problem that upping the limit may only defer.
Have you seen this note? It helped me resolve a similar problem once.
To summarise the link:
Visual GC 现在是 JDK 6 的一部分,它提供了非常漂亮的实时内存图形表示。 您可以看到伊甸园、分代和烫发空间发生了什么。 你只是不明白为什么。
更新:它是我的 JDK 1.6.0_13 发行版中的 bin/jvisualvm.exe。 给它你想要监控的进程的PID。
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.
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.
这里的所有响应都与由于多次重新启动Web应用程序而发生的PermGen问题有关,但在这种情况下,问题已经在tomcat重新启动后的第一次部署时发生,因此它不可能是ClassLoader的引用或commons-logging的问题。
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.
如果您在 jdk6 上运行,则可以使用 jconsole 应用程序来监视应用程序的内存使用情况并进一步调查。
另一种途径是使用探查器,我使用 JProfiler,并用它来查看应用程序。 它会准确地告诉您问题出在哪里。
If you're running on jdk6 then you can use the jconsole app to monitor the memory usage of the application and investigate further.
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.
我遇到了同样的问题,并且我
然后我改用码头,一切都很好,并且应用程序按预期部署/运行。
所以如果tomcat不是必须的,那么我建议Jetty。
I ran in the same problem, and I've read that Tomcat is the culprit in this situation.
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.
-XX:MaxPermSize
确实有效,您只需获得正确的值即可。 我认为,客户端模式 VM 的默认大小为 32mb,服务器模式 VM 的默认大小为 64mb。 如果您有足够的内存,我建议将其设置为 256mb:出现问题的原因是 Spring 和 Hibernate 会大量使用运行时生成的类,有时甚至会使用很多类。 这些生成的类都会进入 PermGen 内存池,因此如果您使用这些框架,通常需要将 PermGen 提升到大量。
The
-XX:MaxPermSize
does 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: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.