我使用JNetPcap库制作了一个数据包嗅探器。它是从另一个监视系统资源(RAM,磁盘使用,活动网络接口,运行进程等)的应用程序执行的.jar。我希望嗅探器在监视器应用程序终止时(由用户与否)自行关闭,并且我考虑使用监视器应用程序创建文件并使用fileLock将其锁定。然后在嗅探器的每个循环上,我检查文件是否仍然被锁定,如果不是(意味着监视器应用程序已终止),那么我将调用System.exit(0);
问题在于,非分页内核内存使用量(实际上,它不仅仅是非分页内核内存)在执行时会非常快速地上升。当我单独执行它时不会发生。
当我同时运行它时也不会发生这种情况,但是嗅探器应用程序中的以下代码被评论(负责检查监视器创建的文件是否仍然被锁定)< / p>
private void checkReleasedLock() throws IOException{
File file = new File("config\\file.lock");
FileChannel channel = new RandomAccessFile(file, "rw").getChannel();
FileLock lock = null;
try {
lock = channel.tryLock();
if(lock != null){ //It acquired the lock => the other application is terminated.
System.exit(0);
} else {
file = null;
channel = null;
lock = null;
}
} catch (Exception e) {
file = null;
channel = null;
lock = null;
}
}
为了向您展示内存使用量的增加,这是记录系统资源的监视器应用程序的输出:
######################################
# Beginning log: 2012-08-03 10:14:26 #
######################################
__________
RAM USAGE:
Total: 2040 MB
Free: 1260 MB (63.31 %)
Used: 720 MB (36.69 %)
Swap total: 4125 MB
Swap used: 1104 MB
Swap free: 3021 MB
Kernel Memory Total: 75876 KB
Paged: 52536 KB
Nonpaged: 23340 KB
几个小时后......
######################################
# Beginning log: 2012-08-03 12:14:27 #
######################################
__________
RAM USAGE:
Total: 2040 MB
Free: 1000 MB (50.37 %)
Used: 980 MB (49.63 %)
Swap total: 4125 MB
Swap used: 1307 MB
Swap free: 2818 MB
Kernel Memory Total: 213724 KB
Paged: 173724 KB
Nonpaged: 40000 KB
该代码有问题吗?它可能是内存泄漏的原因吗?
答案 0 :(得分:2)
该代码有问题吗?
看起来每次调用该方法时,都会创建一个未关闭的FileChanel对象。分配null
不会导致任何事情被关闭。
您应该像这样编码以确保FileChanel始终关闭:
private void checkReleasedLock() throws IOException {
File file = new File("config\\file.lock");
FileChannel channel = new RandomAccessFile(file, "rw").getChannel();
FileLock lock;
try {
lock = channel.tryLock();
if (lock != null) {
System.exit(0);
}
} finally {
channel.close();
}
}
请注意,我还修复了导致所有异常被压扁的错误。
可能是内存泄漏的原因吗?
是的,可能是。使用原始形式的代码,只有在Java垃圾收集器完成对象时才会关闭打开的文件通道。在此之前,每个人都将占用操作系统资源,这很好地解释了未增加的未内核内存使用量。