运行此Java应用程序时,非分页内核内存疯狂增加

时间:2012-08-16 12:09:47

标签: java windows memory-leaks ram file-locking

我使用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

该代码有问题吗?它可能是内存泄漏的原因吗?

1 个答案:

答案 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垃圾收集器完成对象时才会关闭打开的文件通道。在此之前,每个人都将占用操作系统资源,这很好地解释了未增加的未内核内存使用量。