问题:有一个JAVA应用会频繁地创建文件,完成业务逻辑后会删除该文件,但是发现磁盘已使用空间一直在增长。
1、查看标记为删除,但是未释放空间的文件(root账号)
root# lsof | grep deleted
java 27870 mq 253u REG 8,3 33556584 4325563 /***/db-4970.log (deleted)
java 27870 mq 254u REG 8,3 33558799 4325567 /***/db-4972.log (deleted)
java 27870 mq 255u REG 8,3 33557564 4325551 /***/db-4969.log (deleted)
java 27870 mq 256u REG 8,3 33558446 4325565 /***/db-4971.log (deleted)
java 27870 mq 257u REG 8,3 33554898 4325569 /***/db-4973.log (deleted)
java 27870 mq 258u REG 8,3 33554976 4325571 /***/db-4974.log (deleted)
....
发现JAVA进程27870对这些标记为删除的文件有引用
2、根据业务大致知道这些文件在那几个地方被使用,查看jvm heap中的实例数,确认这一点。
>$./jmap -histo:live 27870 > ~/27870.txt
间隔一段时间多次输出,发现与文件对象相关实例一直在增加:
第一次:
70: 179 5728 java.io.RandomAccessFile
71: 233 5592 java.io.FileDescriptor
---------------------------------------------------------------
第二次:
66: 204 6528 java.io.RandomAccessFile
69: 259 6216 java.io.FileDescriptor
-------------------------------------------------------------------
第三次:
64: 220 7040 java.io.RandomAccessFile
68: 267 6408 java.io.FileDescriptor
-------------------------------------------------------------------
3、输出 jvm heap,分析java.io.RandomAccessFile被那些对象引用
>$jmap -dump:live,format=b,file=~/27870.dump 27870
4、使用jhat进行分析
>$jdk1.6/bin/jhat ~/27870.dump
Reading from /home/web/27870.dump
Dump file created Wed Nov 06 11:16:53 CST 2013
Snapshot read, resolving...
Resolving 123572 objects...
Chasing references, expect 24 dots........................
Eliminating duplicate references........................
Snapshot resolved.
Started HTTP server on port 7000
Server is ready.
5、打开浏览器http://localhost:7000
点击页面下面的链接
Show heap histogram
然后查找RandomAccessFile,点开对应的链接。
通过References (summary) by Type 中对应的信息,一层一层往上找,直到找到对应的业务类,这样就大致可以定位到在哪个类中有引用了,再分析业务代码找到引用没有释放的地方。