我修复了 3 个不同的 PermGen
OutOfMemoryError
webapp 中存在问题,并且它可以在受限制的 -XX:MaxPermSize=66m
中进行任意数量的重新部署(我不会尝试超过 30 个)。 。运行应用程序需要约 55 MB 的 PermGen
.
修复内存泄漏的主要原因是为了练习和让开发环境更愉快 - with <Context reloadable="true">
编译后,我的 web 应用程序在 3 秒后已重新部署!
刚才我发现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 来同时保存至少 2 个应用程序实例?我相信有时垃圾收集器需要多次传递才能删除所有引用,因此需要为 GC 释放一个实例并加载另一个实例提供一些“余量”。
- 尝试切换到另一个垃圾收集器。我遇到过只能用 GC 和 Parallell 中的错误来解释的情况,CMS 和 G1 在这些情况下的行为有所不同。
- 如果您想尝试其他方法来查找 GC 根路径,可以查看 this blog series of mine或Arit .
- 您可能还想通过添加我的 ClassLoader Leak Prevention Library 来查看问题是否得到解决。到您的应用程序。如果是,请查看日志以了解潜在原因。
关于java - "No GC root found"时 PermGen OutOfMemoryError 的原因?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34475032/