使用Jetty 7重新部署时解决PermGen问题

6
经过几天的调试,我成功地在Tomcat 6.0.32上重新部署了一款中大型Web应用程序,而没有出现任何PermGen泄漏。当它被填满时,我看到了PermGen的下降,并且类加载器被垃圾回收了。
在庆祝了很久之后,我尝试在我们的开发环境(由Maven和Jetty插件组成)上使应用程序重新部署,以避免泄漏。
不幸的是,我似乎遇到了服务器限制,如下面的截图所示。
Jetty请求线程对BeanElResolver有一个强引用,而BeanElResolver又对我的Web应用程序中的多个类有一个强引用。
我找不到如何清除这些信息的参考。
我该如何从我的应用程序中移除这个最终的PermGen泄漏?

更新:

我尝试了以下方法来解决问题,但都没有成功:

  • 升级到最新版本的Jetty插件(7.4.5和8.0.0.M3)
  • 使用CMS收集器:-XX:+UseConcMarkSweepGC -XX:+CMSClassUnloadingEnabled

更新 2:


我不理解你的措辞。PermGen-Leak是什么意思?你是否尝试向VM提供一些GC相关的标志,例如:-XX:+CMSPermGenSweepingEnabled -XX:+CMSClassUnloadingEnabled?你是否期望在没有连接/会话时完全收集运行中的Web应用程序? - Angel O'Sphere
默认情况下,你的Servlet容器在每次重新部署时会泄漏类加载器。类定义是分配在永久代中的,所以你会遇到PermGen泄漏。我惊讶于OP如何在Tomcat 6和无标志的情况下绕过了这个问题。 - Daniel Lyons
Robert:请考虑告诉我们更多关于你是如何修复Tomcat 6中的漏洞的!我很想知道你做了什么。也许可以在维基上分享一下吗? - Daniel Lyons
@Angel:我不使用CMS垃圾收集器,所以我不需要指定那些标志。而且,当我提到PermGen泄漏时,我是指在未卸载时,旧的类加载器实例仍然固定在内存中,不允许对这些类进行垃圾回收。 - Robert Munteanu
这就是为什么我建议使用另一个GC,标准GC根本不会收集PermGen,如果我没记错的话。 - Angel O'Sphere
2个回答

2

这是EL实现中的一个实际漏洞,最新的Jetty版本已经解决了这个问题。

一旦发布,版本7.5.0将包含此修复程序。


0

虽然这不是你问题的直接答案,但你可以考虑在开发中使用JRebel。使用JRebel,你大多数情况下不需要重新部署,从而避免了permgen泄漏和重新部署浪费时间的问题。我一直在使用它,效果非常好。


我已经在使用JRebel,但是a)有时候我不得不重启,b)并且我的团队中并不是每个人都这样做,所以我需要为他们找到更好的解决方案。 - Robert Munteanu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接