Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Releasing resources of Java 7 WatchService

I am using Java 7 WatchService to watch directories. I constantly change which directories i am watching. I run into the exception:

java.io.IOException: The network BIOS command limit has been reached.

after 50 directories. I am certain i call close() on each WatchService i create before creating a new one.

Does anyone know the proper way to release a WatchService so you do not run into this limit?

Thanks,

Dave

like image 237
Dave Avatar asked Jul 07 '12 06:07

Dave


2 Answers

I think that all you need to do is close() the service. I know you said that you think that you do this already, but I suspect that you are missing some. For instance, you could be failing to close service instances in the case of an exception. You should treat a WatchService instance as other IO resources and close it in a finally block; e.g.

WatchService ws = ...
try {
    // use it ...
} finally {
    ws.close();
}

or using the Java 7 "try with resource" syntax.

try (WatchService ws = ...) {
    // use it ...
}

When the WatchService is closed, it should immediately free any O/S level resources that it holds.


The only other possibility is that you have run into some Java bug in the WatchService implementation.

like image 139
Stephen C Avatar answered Oct 31 '22 16:10

Stephen C


If I am reading the Javadoc right, you need only one WatchService, which you instantiate at start and close() at end of app.

You submit via .register the paths and events you want to register one at a time, and get back a WatchKey. You keep these WatchKeys around, perhaps in a ConcurrentMap keyed by Path.

When you want to remove one, simply call cancel() on the WatchKey and remove from Map.

WatchService

Path.Register

WatchKey

like image 34
MJB Avatar answered Oct 31 '22 17:10

MJB