我在webapp中修复了3个不同的PermGen
OutOfMemoryError
问题,在受限制的-XX:MaxPermSize=66m
中,它可以在任意数量的重新部署(我尝试不超过30个)的情况下保留下来。正在运行的应用程序需要约55 MB的PermGen
。
解决内存泄漏的主要原因是要练习并使开发环境更加舒适-编译后使用<Context reloadable="true">
并在3秒钟后重新部署了我的webapp!
刚才我在catalina.out
中发现错误:
Dec 26, 2015 5:28:09 PM org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor run
SEVERE: Unexpected death of background thread ContainerBackgroundProcessor[StandardEngine[Catalina]]
java.lang.OutOfMemoryError: PermGen space
Exception in thread "ContainerBackgroundProcessor[StandardEngine[Catalina]]"
Exception: java.lang.OutOfMemoryError thrown from the UncaughtExceptionHandler in thread "ContainerBackgroundProcessor[StandardEngine[Catalina]]"
像往常一样,我运行
visualvm
并运行OQL:select unique(map(heap.objects('java.lang.ClassLoader'), 'classof(it)'))
并查看
org.apache.catalina.loader.WebappClassLoader
实例。 OQL可以描述我的实际工作:filter(heap.objects('org.apache.catalina.loader.WebappClassLoader'),
'it.state.name.toString() == "DESTROYED"')
该实例没有释放
PermGen
内存。但是,当我调用“查找最近的GC根”时,找不到“ GC根”。PermGen OutOfMemoryError
产生No GC root found
的原因是什么?OutOfMemoryError
的原因是否可能是在重新部署期间正在处理应用程序请求?我将特别低的
PermGen
设置为在应用程序重新部署期间强制在PermGen中使用GC,因为PermGen
仅在内存压力下清除-我决定监视OutOfMemoryError是否仍然影响我的应用程序。 最佳答案
有几件事值得一看。
您是否有足够的PermGen可以同时容纳至少两个应用程序实例?我认为有时需要使用垃圾收集器多次传递才能删除所有引用,因此对于为GC释放一个实例并加载另一个实例,需要有一定的“余量”。
尝试切换到另一个垃圾收集器。我已经看到了只能用GC和Parallell中的错误来解释的情况,CMS和G1在这些情况下的行为有所不同。
如果您想尝试其他方法来查找GC根路径,可以查看this blog series of mine或Arit。
您可能还想通过将我的ClassLoader Leak Prevention Library添加到您的应用程序来查看问题是否得到解决。如果是这种情况,请查看日志以了解潜在原因。
关于java - “未找到GC根目录”时出现PermGen OutOfMemoryError的原因?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/34475032/