重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
这篇文章将为大家详细讲解有关如何从JVM heap dump里查找没有关闭文件的引用,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。
创新互联云计算的互联网服务提供商,拥有超过13年的服务器租用、川西大数据中心、云服务器、虚拟空间、网站系统开发经验,已先后获得国家工业和信息化部颁发的互联网数据中心业务许可证。专业提供云主机、虚拟空间、空间域名、VPS主机、云服务器、香港云服务器、免备案服务器等。
最近排查一个文件没有关闭的问题,记录一下。
哪些文件没有关闭是比较容易找到的,查看进程的fd(File Descriptor)就可以。但是确定fd是在哪里被打开,在哪里被引用的就复杂点,特别是在没有重启应用的情况下。
在JVM里可以通过heap dump比较方便地反查对象的引用,从而找到泄露的代码。
以下面简单的demo为例,Demo会创建一个临时文件,并且没有close掉:
1 2 3 4 5 6 7 8 9 10 11 |
|
进程打开的文件在OS里有对应的fd(File Descriptor),可以用lsof命令或者直接在linux下到/proc
目录下查看。
以demo为例,可以找到test文件的fd是12:
1 2 3 4 5 6 7 8 |
|
使用jmap命令:
1 |
|
java.io.FileDescriptor
对象对于每一个打开的文件在JVM里都有一个java.io.FileDescriptor
对象。查看下源码,可以发现FileDescriptor
里有一个fd
字段:
1 2 |
|
所以需要查找到fd等于12的FileDescriptor
,QOL语句:
1 |
|
在jdk8里自带VisualVM,jdk9之后可以单独下载:https://visualvm.github.io/
把heap dump文件导入VisualVM里,然后在“OQL控制台”查询上面的语句,结果是:
再可以查询到parent,引用相关的对象。
除了VisualVM还有其它很多heap dump工具,在jdk里还自带一个jhat工具,尽管在jdk9之后移除掉了,但是个人还是比较喜欢这个工具,因为它是一个web接口的。
访问 http://localhost:7000/oql/ ,可以在浏览器里查询OQL:
打开链接可以查看具体的信息
先找出没有关闭文件的fd
从heap dump里据fd找出对应的java.io.FileDescriptor
对象,再找到相关引用
关于如何从JVM heap dump里查找没有关闭文件的引用就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。