digitalpetri / modbus

Modbus TCP, Modbus RTU/TCP, and Modbus RTU/Serial for Java 17+.
Eclipse Public License 2.0
638 stars 218 forks source link

How to release all resources? #11

Closed vbnetvbnet closed 7 years ago

vbnetvbnet commented 7 years ago

When I shutdown Tomcat server, it failed to close modbus related resources. Here is the error report:

11-Apr-2017 20:31:51.656 WARNING [localhost-startStop-2] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [ROOT] appears to have started a thread named [pool-41-thread-1] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
    java.lang.Thread.sleep(Native Method)
    io.netty.util.HashedWheelTimer$Worker.waitForNextTick(HashedWheelTimer.java:461)
    io.netty.util.HashedWheelTimer$Worker.run(HashedWheelTimer.java:360)
    java.lang.Thread.run(Thread.java:745)
11-Apr-2017 20:31:51.657 WARNING [localhost-startStop-2] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [ROOT] appears to have started a thread named [nioEventLoopGroup-2-1] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
    sun.nio.ch.WindowsSelectorImpl$SubSelector.poll0(Native Method)
    sun.nio.ch.WindowsSelectorImpl$SubSelector.poll(WindowsSelectorImpl.java:296)
    sun.nio.ch.WindowsSelectorImpl$SubSelector.access$400(WindowsSelectorImpl.java:278)
    sun.nio.ch.WindowsSelectorImpl.doSelect(WindowsSelectorImpl.java:159)
    sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:86)
    sun.nio.ch.SelectorImpl.select(SelectorImpl.java:97)
    io.netty.channel.nio.NioEventLoop.select(NioEventLoop.java:622)
    io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:310)
    io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:112)
    io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:137)
    java.lang.Thread.run(Thread.java:745)
11-Apr-2017 20:31:51.657 WARNING [localhost-startStop-2] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [ROOT] appears to have started a thread named [threadDeathWatcher-3-1] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
    java.lang.Thread.sleep(Native Method)
    io.netty.util.ThreadDeathWatcher$Watcher.run(ThreadDeathWatcher.java:147)
    io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:137)
    java.lang.Thread.run(Thread.java:745)
11-Apr-2017 20:31:51.658 WARNING [localhost-startStop-2] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [ROOT] appears to have started a thread named [ForkJoinPool-1-worker-1] 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.ForkJoinPool.awaitWork(ForkJoinPool.java:1824)
    java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1693)
    java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)
11-Apr-2017 20:31:51.659 WARNING [localhost-startStop-2] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [ROOT] appears to have started a thread named [nioEventLoopGroup-2-2] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
    sun.nio.ch.WindowsSelectorImpl$SubSelector.poll0(Native Method)
    sun.nio.ch.WindowsSelectorImpl$SubSelector.poll(WindowsSelectorImpl.java:296)
    sun.nio.ch.WindowsSelectorImpl$SubSelector.access$400(WindowsSelectorImpl.java:278)
    sun.nio.ch.WindowsSelectorImpl.doSelect(WindowsSelectorImpl.java:159)
    sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:86)
    sun.nio.ch.SelectorImpl.select(SelectorImpl.java:97)
    io.netty.channel.nio.NioEventLoop.select(NioEventLoop.java:622)
    io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:310)
    io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:112)
    io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:137)
    java.lang.Thread.run(Thread.java:745)
11-Apr-2017 20:31:51.661 SEVERE [localhost-startStop-2] org.apache.catalina.loader.WebappClassLoaderBase.checkThreadLocalMapForLeaks The web application [ROOT] created a ThreadLocal with key of type [java.lang.ThreadLocal] (value [java.lang.ThreadLocal@2bf57c77]) and a value of type [io.netty.util.internal.InternalThreadLocalMap] (value [io.netty.util.internal.InternalThreadLocalMap@5eeed32c]) but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak.
11-Apr-2017 20:31:51.662 SEVERE [localhost-startStop-2] org.apache.catalina.loader.WebappClassLoaderBase.checkThreadLocalMapForLeaks The web application [ROOT] created a ThreadLocal with key of type [java.lang.ThreadLocal] (value [java.lang.ThreadLocal@2bf57c77]) and a value of type [io.netty.util.internal.InternalThreadLocalMap] (value [io.netty.util.internal.InternalThreadLocalMap@50fcdab9]) but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak.
11-Apr-2017 20:31:51.662 SEVERE [localhost-startStop-2] org.apache.catalina.loader.WebappClassLoaderBase.checkThreadLocalMapForLeaks The web application [ROOT] created a ThreadLocal with key of type [java.lang.ThreadLocal] (value [java.lang.ThreadLocal@2bf57c77]) and a value of type [io.netty.util.internal.InternalThreadLocalMap] (value [io.netty.util.internal.InternalThreadLocalMap@148dc3df]) but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak.

Could you take a look and tell me which methods should I call when shutting down my Tomcat server, thread pool#shutdown() or future#close() or something else? Thanks.

kevinherron commented 7 years ago

Try calling Modbus.releaseSharedResources().

If that's not enough, you may have to convince Netty to release some as well:

InternalThreadLocalMap.destroy()
FastThreadLocal.removeAll()
vbnetvbnet commented 7 years ago

Thanks, but this still doesn't work. I'm gonna try some other methods tomorrow.

kevinherron commented 7 years ago

I have an open issue with Netty that may be causing this: https://github.com/netty/netty/issues/6565

vbnetvbnet commented 7 years ago

Great! I 'll keep tuned.

vbnetvbnet commented 7 years ago

@kevinherron I tested again carefully and fortunately it worked, by calling Modbus.releaseSharedResources() alone. But I have to add Thread.sleep(3000) because Tomcat doesn't wait subtasks to complete.

vbnetvbnet commented 7 years ago

Here is what has caused this problem. I called this method in a WriteSingleRegisterRequest. But the server just write the value and has no response(WriteSingleRegisterResponse) data at all. In this case, the future.thenAccept(response -> {...}); will never be called. And it just wait.