2

我有一个泄漏文件描述符的网络应用程序。在生产环境中,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 中的一个对象,以便我可以探索哪些对象被留下,以及谁持有对附加文件描述符的对象的引用。

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

在不重新启动JVM的情况下如何做到这一点?是否有任何转储工具可以帮助我解决这种特定情况?

4

1 回答 1

0

您需要的是虚拟机的堆转储。

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

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

会为你做这件事。

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

于 2015-02-19T16:27:11.687 回答