我有一个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;
}
}
答案 0 :(得分:2)
看起来好像你没有在代码中的任何地方调用java.nio.file.WatchService.close()
; java.nio.file.WatchService
实现java.io.Closeable
,这意味着您可以通过使用try-with-resources(自Java 7以来可用)轻松确保消除与java.nio.file.WatchService
的不当使用相关的任何内存泄漏块如此:
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 spec,阅读文档通常会有很多帮助。
The close method may be invoked at any time to close the service causing any threads waiting to retrieve keys, to throw ClosedWatchServiceException.