温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

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

发布时间:2021-10-23 16:24:36 来源:亿速云 阅读:205 作者:柒染 栏目:云计算

这篇文章将为大家详细讲解有关如何从JVM heap dump里查找没有关闭文件的引用,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。

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

哪些文件没有关闭是比较容易找到的,查看进程的fd(File Descriptor)就可以。但是确定fd是在哪里被打开,在哪里被引用的就复杂点,特别是在没有重启应用的情况下。
在JVM里可以通过heap dump比较方便地反查对象的引用,从而找到泄露的代码。

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

1

2

3

4

5

6

7

8

9

10

11

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:

1

2

3

4

5

6

7

8

$ 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命令:

1

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

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

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

1

2

public final class FileDescriptor {

    private int fd;

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

1

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

使用VisualVM里的OQL控制台查询

在jdk8里自带VisualVM,jdk9之后可以单独下载:https://visualvm.github.io/

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

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

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

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

使用jhat查询

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

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

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

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

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

  • 先找出没有关闭文件的fd

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

关于如何从JVM heap dump里查找没有关闭文件的引用就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

jvm
AI