PermGen OutOfMemoryError的原因当"没有找到GC根"?

时间:2015-12-26 20:37:08

标签: java out-of-memory permgen

我在网络应用中修复了3个不同的PermGen OutOfMemoryError个问题,并且在限制-XX:MaxPermSize=66m中可以进行任意数量的重新部署(我不会尝试大于30)。运行应用程序需要大约55 MB的PermGen

修复内存泄漏的主要原因是练习并使开发环境更加愉快 - 编译后<Context reloadable="true">我的webapp在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 OutOfMemoryErrorNo GC root found的原因是什么?

OutOfMemoryError在重新部署期间处理应用程序请求的原因是否可能?

我特别低PermGen在应用程序重新部署期间强制执行PermGen中的GC,因为PermGen仅在内存压力下清理 - 我决定监视OutOfMemoryError是否仍会影响我的应用程序。

1 个答案:

答案 0 :(得分:1)

有一些值得关注的事情。

  1. 您是否有足够的PermGen可以同时保留至少2个应用程序实例?我相信有时需要垃圾收集器多次传递才能删除所有引用,因此需要为GC释放一个实例并加载另一个实例的某些“边距”。
  2. 尝试切换到另一个垃圾收集器。我已经看到了我只能用GC和Parallell中的错误解释的情况,CMS和G1在这些情况下表现不同。
  3. 如果您想尝试另一种方法来查找GC根路径,可以查看this blog series of mineArit
  4. 您可能还想通过将ClassLoader Leak Prevention Library添加到您的应用来查看问题是否得到解决。如果是,请查看日志以了解潜在原因。