我有一个WatchService
用于监视文件夹中的新文件和修改文件。
问题:应用程序在tomcat
服务器上运行,当我关闭服务器时,记录以下错误消息(加上它需要很长时间直到服务器关闭):
01-Oct-2015 08:58:11.998 WARNING [localhost-startStop-2] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [myapp] appears to have started a thread named [Thread-5] but has failed to stop it. This is very likely to create a memory leak.
Stack trace of thread:
sun.nio.fs.WindowsNativeDispatcher.GetQueuedCompletionStatus0(Native Method)
sun.nio.fs.WindowsNativeDispatcher.GetQueuedCompletionStatus(Unknown Source)
sun.nio.fs.WindowsWatchService$Poller.run(Unknown Source)
java.lang.Thread.run(Unknown Source)
01-Oct-2015 08:58:11.998 WARNING [localhost-startStop-2] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [myapp] appears to have started a thread named [SimpleAsyncTaskExecutor-2] but has failed to stop it. This is very likely to create a memory leak.
Stack trace of thread:
sun.misc.Unsafe.park(Native Method)
java.util.concurrent.locks.LockSupport.park(Unknown Source)
java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(Unknown Source)
java.util.concurrent.LinkedBlockingDeque.takeFirst(Unknown Source)
java.util.concurrent.LinkedBlockingDeque.take(Unknown Source)
sun.nio.fs.AbstractWatchService.take(Unknown Source)
我该如何解决这个问题?我的值班和往常一样:
WatchService watchService = FileSystems.getDefault().newWatchService();
Path path = Paths.get(folder);
path.register(watchService, events);
WatchKey key = null;
while (true) {
try {
key = watchService.take();
for (WatchEvent<?> event : key.pollEvents()) {
//etc
}
key.reset();
} catch (ClosedWatchServiceException e) {
break;
}
}
看起来好像你没有调用java.nio.file.WatchService.close()
在你的代码的任何地方;java.nio.file.WatchService
实现了java.io.Closeable
,这意味着你可以很容易地确保你摆脱任何与不正确使用java.nio.file.WatchService
相关的内存泄漏,通过使用一个尝试资源(自Java 7以来可用)块,如下所示:
try(WatchService watchService = FileSystems.getDefault().newWatchService()) {
Path path = Paths.get(folder);
path.register(watchService, events);
WatchKey key = null;
while (true) {
try {
key = watchService.take();
for (WatchEvent<?> event : key.pollEvents()) {
//etc
}
key.reset();
} catch(InterruptedException | ClosedWatchServiceException e) {
Thread.currentThread().interrupt();
}
}
}
还请看看WatchService java规范,阅读文档通常会有很大帮助。
The close method may be invoked at any time to close the service causing any threads waiting to retrieve keys, to throw ClosedWatchServiceException.