• 极客专栏正式上线!欢迎访问 https://www.jikewenku.com/topic.html
  • 极客专栏正式上线!欢迎访问 https://www.jikewenku.com/topic.html

从 JVM heap dump 里查找没有关闭文件的引用

技术杂谈 勤劳的小蚂蚁 3个月前 (01-30) 79次浏览 已收录 0个评论 扫描二维码


背景

最近排查一个文件没有关闭的问题,记录一下。

哪些文件没有关闭是比较容易找到的,查看进程的fd(File Descriptor)就可以。但是确定fd是在哪里被打开,在哪里被引用的就复杂点,特别是在没有重启应用的情况下。

JVM里可以通过heap dump比较方便地反查对象的引用,从而找到泄露的代码。

以下面简单的demo为例,Demo会创建一个临时文件,并且没有close掉:

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
public class Test {
public static void main(String[] args) throws IOException {
File tempFile = File.createTempFile(“test”, “ttt”);
FileInputStream fi = new FileInputStream(tempFile);

System.in.read();
}
}

通过文件名查找对应的fd

进程打开的文件在OS里有对应的fd(File Descriptor),可以用lsof命令或者直接在linux下到/proc目录下查看。

以demo为例,可以找到test文件的fd是12:

$ ls -alh /proc/11278/fd/
total 0
dr-x—— 2 admin users  0 Jun 30 18:20 .
dr-xr-xr-x 8 admin users  0 Jun 30 18:20 ..
lrwx—— 1 admin users 64 Jun 30 18:20 0 -> /dev/pts/0
lrwx—— 1 admin users 64 Jun 30 18:20 1 -> /dev/pts/0
lr-x—— 1 admin users 64 Jun 30 18:24 11 -> /dev/urandom
lr-x—— 1 admin users 64 Jun 30 18:24 12 -> /tmp/test7607712940880692142ttt

对进程进行heap dump

使用jmap命令:

jmap -dump:live,format=b,file=heap.bin 11278

通过OQL查询java.io.FileDescriptor对象

对于每一个打开的文件在JVM里都有一个java.io.FileDescriptor对象。查看下源码,可以发现FileDescriptor里有一个fd字段:

public final class FileDescriptor {
    private int fd;

所以需要查找到fd等于12的FileDescriptor,QOL语句:

select s from java.io.FileDescriptor s where s.fd == 12

使用VisualVM里的OQL控制台查询
在jdk8里自带VisualVM,jdk9之后可以单独下载:https://visualvm.github.io/

把heap dump文件导入VisualVM里,然后在“OQL控制台”查询上面的语句,结果是:


再可以查询到parent,引用相关的对象。

使用jhat查询

除了VisualVM还有其它很多heap dump工具,在jdk里还自带一个jhat工具,尽管在jdk9之后移除掉了,但是个人还是比较喜欢这个工具,因为它是一个web接口的。

jhat -port 7000 heap.bin

访问 http://localhost:7000/oql/ ,可以在浏览器里查询OQL:


打开链接可以查看具体的信息

总结

  • 先找出没有关闭文件的fd
  • 从heap dump里据fd找出对应的java.io.FileDescriptor对象,再找到相关引用

链接


丨极客文库, 版权所有丨如未注明 , 均为原创丨
本网站采用知识共享署名-非商业性使用-相同方式共享 3.0 中国大陆许可协议进行授权
转载请注明原文链接:从 JVM heap dump 里查找没有关闭文件的引用
喜欢 (0)
[247507792@qq.com]
分享 (0)
勤劳的小蚂蚁
关于作者:
温馨提示:本文来源于网络,转载文章皆标明了出处,如果您发现侵权文章,请及时向站长反馈删除。

您必须 登录 才能发表评论!

  • 精品技术教程
  • 编程资源分享
  • 问答交流社区
  • 极客文库知识库

客服QQ


QQ:2248886839


工作时间:09:00-23:00