4

我有一个 webapp,它受到类加载器泄漏的影响,因为在多次重新部署 webapp 后 PermGen 内存不足。

Google 和网络上的几个乐于助人的人告诉我,调查此类问题的方法是在分析器中打开内存转储,定位有故障的类加载器,并查看导致该加载器的 GC 根路径。使用 Yourkit 这样做,我可以发现由于 Drools 的 CompositeClassLoader 导致的泄漏,甚至设法解决它。我认为。

但是在应用修复后,我仍然看到类加载器在重新部署后没有被 GC。当我向 Yourkit 询问加载程序的路径时,它实际上可以显示数百条路径。请不要告诉我这是我必须调查的泄漏数量!

Yourkit 截图

(前两条路径来自 Drools,我在修复之前拍摄了快照。我还隐藏了我的公司包名称,以避免任何投诉。)

更令人困惑的是,如果我使用选项卡Paths to loader ( Alt+3) 与使用命令Paths from GC root ( Ctrl+P) 会打开一个新选项卡,我不会得到相同的路径:

在此处输入图像描述

所以我想明白:

  • 这个“加载器路径”选项卡到底显示了什么?引用此类加载器的类列表?但是,与“类列表”选项卡有什么区别?什么是合并路径Paths to loaderPaths from GC root有什么区别?我无法准确理解这些选项卡显示的内容,Yourkit 的文档只说“加载程序选项卡的路径显示加载程序的路径。”...
  • 更一般地说,我如何在这么多数据中找到罪魁祸首?

我提到 Yourkit 是因为这是我使用和熟悉的(至少对于其他分析任务),以防它有任何特殊之处,但我认为这与其他内存转储分析器非常相似。我的Yourkit版本是8.0。

4

1 回答 1

1

this is the way that Yourkit recommends to find the classloader leaks, they go through it here:

  • reproduce the problem with one redeploy, for a scenario of 2 classloaders, one leaked and one current
  • click on classloaders tab
  • Sort classloaders by 'number of classes without instances'
  • the leaked classloader will have lots of classes without instances, the instances have been collected but not the classes and the classloader itself, causing the permgen leak
  • once the leaked classloader is identified, select 'Paths to Loader'
  • the paths to the loader should be shown, there should be less than a handful

This is an example of a leak found:

classloader leak

This is the image that your are looking for, on top you have the leaked classloader, on the bottom you have the reason for the leak.

Usually the leak is caused by a static variable at a server classloader that holds references to objects on the leaked classloader (for example a JDBC driver shipped inside the WAR), or a thread started by the first classloader that outlived the deplyment and contains a thread local variable with a reference to an object of the ancient classloader.

于 2014-04-08T21:30:07.717 回答