案例——文件句柄(pipe)增多tomcat模块定位方法

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/abcyyjjkk/article/details/82182038

问题描述:tomcat文件句柄数持续增长

定位方法:

定位文件句柄泄漏前需要收集的必要信息:

  1. tomcat初始启动时的文件句柄数、对tomcat的详细lsof结果、以及tomcat的内存dump;
  2. 按时间段对tomcat的文件句柄数进行统计(每小时、每半天、每天、隔天);
  3. 若在时间段范围内增长幅度较大(超过100个),则按该时间段连续几次(至少三次)取:tomcat的详细lsof结果、tomcat的内存dump;
  4. tomcat中运行了哪些模块,以及每个模块的版本;
  5. 各模块的源码;

  7. 根据比较结果中出现差异的对象内存地址(如:0x7c667670)在“incoming reference”列表中找到对应项,逐级展开引用到项目中使用的类所在条目:

 8.右键 -> List objects -> with outgoing references

  1. 使用lsof -p <tomcat-pid>查看具体增多的文件句柄为 pipe/eventpoll(或inode);
  2. 使用 jmap -dump:format=b,file=xxxx.dmp <tomcat-pid> 多次抓取内存dump(时间间隔依据增长频度来定,增长很快可以隔几分钟抓取,增长较慢可以隔天抓取);
  3. 使用Eclipse打开这两个内存dump文件;(MAT, Memory Analyzer Tool 插件)
  4. 在“Histogram”中搜索“sun.nio.ch.EPollSelectorImpl”(Linux平台上的NIO Selector实现类);
  5. 右键 -> List objects -> with incoming reference
  6. 分别全选结果(两个内存dump),右键 -> Copy -> Selection,放入文本编辑器中进行比较;

9.逐级展开“classloader”到 WebappClassLoader

10.结果中的 contextName 属性对应的值就是该对象所在 webapps 中的路径。 

问题总结:

1、该实例中的文件句柄泄漏为pipe/eventpoll泄漏,这是Java NIO操作未正确关闭Selector所致,文件句柄泄漏发生在Native层面,由于Selector对象已被回收,所以在内存dump中也无法找到对应导致句柄泄漏的Selector对象;

2、注:这种方式找到的只是发生重新创建NIO连接的web模块,这并不一定意味着就是发生文件句柄泄漏的模块;但是,发生文件句柄泄漏就一定意味着有对象重新创建/新创建;所以,这个定位结果对终止问题定位具有较大的参考意义。

 

猜你喜欢

转载自blog.csdn.net/abcyyjjkk/article/details/82182038