java - WatchService导致tomcat内存泄漏?

标签 java tomcat watchservice

我有一个 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 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 通过使用 try-with-resources(自 Java 7 起可用) block ,如下所示:

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.

关于java - WatchService导致tomcat内存泄漏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32881405/

相关文章:

tomcat - Windows 服务器上启动 tomcat 服务的访问权限被拒绝

JavaFX - 在指定目录中创建文件时如何创建新阶段(打开新窗口)?

java - 使用 Java WatchService 监视和解析日志文件

Java - 使用 while 循环丢失第一个用户输入

java - 如何在单元测试中避免 Thread.sleep?

java - 使用 Eclipse 首选项更改缩进未被 TortoiseHG 选择为变更集

tomcat - struts2中的ClearCacheInterceptor

java - 如何在 Android Studio 中比较两个图像的扩展名和名称?

hibernate - Tomcat/Hibernate 问题 "SEVERE: Error listenerStart"

java - java 7 nio 2 程序的意外输出