如何将进程文件描述符映射到java对象

时间:2014-04-23 10:41:09

标签: java debugging file-descriptor resource-leak

我有一个泄露文件描述符的网络应用程序。在生产环境中,java进程上的文件描述符数量会随着时间的推移而缓慢增长,几个月之后就会耗尽文件描述符。文件描述符的当前限制相当高,10240。

在查看java进程时,这就是文件描述符列表的外观:

# ls -l /proc/32526/fd |wc -l
9558

# ls -l /proc/32526/fd
lr-x------ 1 userx userx 64 Apr 23 12:21 1229 -> /data/s1-js2-tier2-store6/52d/2ed/f73/1c80d154a055e5e
lr-x------ 1 userx userx 64 Apr 23 12:21 1230 -> /data/s1-js2-tier2-store6/52d/9aa/ad3/1c80d154a0688a6
lr-x------ 1 userx userx 64 Apr 23 12:21 1231 -> /data/s1-js2-tier2-store4/522/9c8/543/1c81a0c37763880
lr-x------ 1 userx userx 64 Apr 23 12:21 1232 -> /data/s1-js2-tier2-store6/52d/78c/4f3/1c80d154a06308c
lr-x------ 1 userx userx 64 Apr 23 12:21 1239 -> /data/s1-js2-tier2-store6/530/b88/753/1c80901a6d6541f (deleted)

我想要做的是选择一个文件描述符,然后以某种方式将其映射到实时JVM中的对象,以便我可以探索哪些对象被遗留,以及谁拥有对附加了文件描述符的对象的引用。 / p>

我想用Eclipse连接到实时JVM,但要做到这一点,我需要重新启动JVM以添加调试端口/参数,但是需要等待几个月才能出现相同的情况。

如何在不重新启动JVM的情况下执行此操作?是否有任何转储工具可以帮助我解决这个特定情况?

1 个答案:

答案 0 :(得分:0)

您需要的是VM的堆转储。

如果您使用的是jdk 1.7,即使没有事先设置调试,也可以连接到JVM。您应该能够通过shell上的jmap获取堆转储。

jmap -dump:format=b,file=<FILENAME> <PID> 

会为你做这件事。

之后,您可以将堆转储加载到Eclipse MAT中并从那里进行分析。如果泄漏足够严重,那么使用默认报告检测它可能不是很困难。