Question

I've made a packet sniffer using JNetPcap library. It's a .jar that is executed from another application that monitors the system resources (RAM, Disk usage, active network interfaces, running processes, etc). I want the sniffer to close itself when the monitor application is terminated (by the user or not) and I thought about creating a file with the monitor app and locking it using fileLock. Then on every loop of the sniffer I'd check if the file is still locked and if it's not (meaning the monitor app terminated), then I'd call System.exit(0);

The problem is that the amount of nonpaged kernel memory usage (actually, it's not just nonpaged kernel memory) goes up really fast when they're both executing. It doesn't happen when I execute them individually.

It also doesn't happen when I run them simultaneously, but with the following piece of code in the sniffer app commented (responsible for checking whether the file created by the monitor is still locked)

        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;
            }
        }

Just to show you the increase in memory usage, this is the output of the monitor app that logs the system resources:

######################################
# 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

And a couple of hours later...

######################################
# 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

Is something wrong with that code? Could it be the cause of the memory leak?

Was it helpful?

Solution

Is something wrong with that code?

It looks like each time you call that method you will create a FileChanel object that is not closed. Assigning null doesn't cause anything to be closed.

You should code it like this to ensure that the FileChanel is always closed:

   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();
        }
    }

Note that I've also fixed a bug that caused all Exceptions to be squashed.

Could it be the cause of the memory leak?

Yes, it could be. With the code in its original form, the open file channels would only get closed when the objects were finalized by the Java garbage collector. Until then, each one will be tying down operating system resources, and that could well explain the increased unpaged kernel memory usage.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top