溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何從JVM heap dump里查找沒有關閉文件的引用

發(fā)布時間:2021-10-23 16:24:36 來源:億速云 閱讀:201 作者:柒染 欄目:云計算

這篇文章將為大家詳細講解有關如何從JVM heap dump里查找沒有關閉文件的引用,文章內容質量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關知識有一定的了解。

最近排查一個文件沒有關閉的問題,記錄一下。

哪些文件沒有關閉是比較容易找到的,查看進程的fd(File Descriptor)就可以。但是確定fd是在哪里被打開,在哪里被引用的就復雜點,特別是在沒有重啟應用的情況下。
在JVM里可以通過heap dump比較方便地反查對象的引用,從而找到泄露的代碼。

以下面簡單的demo為例,Demo會創(chuàng)建一個臨時文件,并且沒有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對象。查看下源碼,可以發(fā)現(xiàn)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里據(jù)fd找出對應的java.io.FileDescriptor對象,再找到相關引用

關于如何從JVM heap dump里查找沒有關閉文件的引用就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經查實,將立刻刪除涉嫌侵權內容。

jvm
AI