JDK-8164166 : Make sure java/nio/channels tests shutdown asynchronous channel groups
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.nio
  • Affected Version: 9
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2016-08-16
  • Updated: 2023-08-16
  • Resolved: 2016-08-24
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 8 JDK 9
8u401Fixed 9 b134Fixed
Related Reports
Relates :  
Relates :  
Relates :  
Description
The following tests may leave daemon threads after they finished:

java/nio/channels/AsynchronousSocketChannel/Leaky.java
java/nio/channels/AsynchronousChannelGroup/Identity.java

The tests above use AsynchronousChannelGroup.withFixedThreadPool() to create instances of AsynchronousChannelGroup. Leaky.java test doesn't shutdown AsynchronousChannelGroup. Identity.java test uses shutdownNow() method, but this method is not called in "finally" block, so that it may be possible that the test leaves daemon threads.

The tests shouldn't leave daemon threads when they finishes. It may slow down further test execution. If other tests also leave daemon threads, it may cause intermittent test failures, see for example JDK-8160642 and JDK-8162757.
Comments
URL: http://hg.openjdk.java.net/jdk9/jdk9/jdk/rev/59162b94ab98 User: lana Date: 2016-08-31 20:17:52 +0000
31-08-2016

URL: http://hg.openjdk.java.net/jdk9/dev/jdk/rev/59162b94ab98 User: asmotrak Date: 2016-08-24 17:58:32 +0000
24-08-2016

Code review: http://mail.openjdk.java.net/pipermail/nio-dev/2016-August/003845.html
23-08-2016

Here is an example of one daemon thread reported by jstack: "InnocuousThread-1" #2171 daemon prio=5 os_prio=0 tid=0x00007fec1c002000 nid=0x57ea waiting on condition [0x00007fec371fa000] java.lang.Thread.State: WAITING (parking) at jdk.internal.misc.Unsafe.park(java.base@9-ea/Native Method) - parking to wait for <0x00000000e10e35e0> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) at java.util.concurrent.locks.LockSupport.park(java.base@9-ea/LockSupport.java:190) at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(java.base@9-ea/AbstractQueuedSynchronizer.java:2064) at java.util.concurrent.ArrayBlockingQueue.take(java.base@9-ea/ArrayBlockingQueue.java:387) at sun.nio.ch.EPollPort$EventHandlerTask.run(java.base@9-ea/EPollPort.java:262) at java.lang.Thread.run(java.base@9-ea/Thread.java:843) at jdk.internal.misc.InnocuousThread.run(java.base@9-ea/InnocuousThread.java:122) It ran EPollPort$EventHandlerTask; http://hg.openjdk.java.net/jdk9/dev/jdk/file/71716def08ac/src/java.base/linux/classes/sun/nio/ch/EPollPort.java I added the following test which causes a timeout: /* * @test */ public class XHang { public static void main(String[] args) throws Exception { Thread.sleep(10 * 1000 * 1000); } } When I ran java/nio/channels and XHang.java (it ran after java/nio/channels tests), then I didn't notice any daemon threads in jstack output for XHang.java. So, it seems to be intermittent. I updated EPollPort.start() method to print a stack trace to figure out which tests start these daemon threads: diff -r cc9b31691df2 src/java.base/linux/classes/sun/nio/ch/EPollPort.java --- a/src/java.base/linux/classes/sun/nio/ch/EPollPort.java Wed Aug 17 16:03:52 2016 -0700 +++ b/src/java.base/linux/classes/sun/nio/ch/EPollPort.java Mon Aug 22 11:34:00 2016 -0700 @@ -110,6 +110,8 @@ } EPollPort start() { + System.out.println("DEBUG: EPollPort: start threads"); + new Exception().printStackTrace(System.out); startThreads(new EventHandlerTask()); return this; } Then, I ran tier1, tier2 and tier3 groups. The following tests which run in agent VM started EPollPort.EventHandlerTask daemon threads: java/nio/channels/AsynchronousChannelGroup/Basic.java java/nio/channels/AsynchronousChannelGroup/GroupOfOne.java java/nio/channels/AsynchronousChannelGroup/Identity.java java/nio/channels/AsynchronousChannelGroup/Restart.java java/nio/channels/AsynchronousChannelGroup/Unbounded.java java/nio/channels/AsynchronousServerSocketChannel/Basic.java java/nio/channels/AsynchronousSocketChannel/Basic.java java/nio/channels/AsynchronousSocketChannel/DieBeforeComplete.java java/nio/channels/Channels/Basic2.java sample/chatserver/ChatTest.java I am not familiar with EPollPort class, and at first glance, the logic looks quite complex. I suppose that EPollPort.EventHandlerTask daemon threads should be stopped by calling shutdownHandlerTasks() method. I found that shutdownHandlerTasks() method is called in AsynchronousChannelGroupImpl.shutdown() amd AsynchronousChannelGroupImpl.shutdownNow() methods: http://hg.openjdk.java.net/jdk9/dev/jdk/file/71716def08ac/src/java.base/share/classes/sun/nio/ch/AsynchronousChannelGroupImpl.java Maybe some tests don't shutdown AsynchronousChannelGroup instances, and as a result, EPollPort.EventHandlerTask daemon threads keep running. But I am not sure why it happens intermittently. Maybe there is a bug in NIO that EPollPort.EventHandlerTask daemon threads can't be stopped sometimes. We can check the tests above that they always shutdown asynchronous channel groups, and update them to do that if necessary (I think they should shutdown groups in try-finally blocks). If EPollPort.EventHandlerTask daemon threads still appears, then it may be a bug in NIO.
22-08-2016

The following tests call AsynchronousServerSocketChannel.open() and AsynchronousSocketChannel.open() which use the default group: java/nio/channels/AsynchronousChannelGroup/Unbounded.java java/nio/channels/AsynchronousServerSocketChannel/Basic.java java/nio/channels/AsynchronousSocketChannel/Basic.java java/nio/channels/AsynchronousSocketChannel/DieBeforeComplete.java java/nio/channels/Channels/Basic2.java
22-08-2016

I don't have any stat/numbers/etc that show how/if the bug may slow down further test execution. If I am not missing something, even if a daemon thread just waits, it still consumes some JVM resources which may slow down other tests. Key word here is "may", I am not saying that such daemon threads from java/nio/channel tests is the root cause of other test failures. But we've already seen at least twice that other tests failed with timeout, and jstack showed many daemon threads which don't seem to be related to those failed tests (please see JDK-8162757 and JDK-8162757 for details). Right now this bug looks like one of many to ensure that tests running in agent VM mode don't leave any resources behind. I mentioned JDK-8162757 and JDK-8162757 because I believe this bug might "help" those tests to fail. I think it would be better to enhance java/nio/tests to make sure they don't leave daemon threads, and then keep working on other tests if they still keep failing.
17-08-2016

The comment in the description "It may slow down further test execution." seem dubious, is there any evidence of this or is this bug one of many to ensure that tests running in agent VM mode don't leave any resources behind.
17-08-2016

I also noticed the following in the spec for AsynchronousChannelGroup class: http://download.java.net/java/jdk9/docs/api/java/nio/channels/AsynchronousChannelGroup.html ... In addition to groups created explicitly, the Java virtual machine maintains a system-wide default group that is constructed automatically. Asynchronous channels that do not specify a group at construction time are bound to the default group. The default group has an associated thread pool that creates new threads as needed. The default group may be configured by means of system properties defined in the table below. Where the ThreadFactory for the default group is not configured then the pooled threads of the default group are daemon threads. ... For example, AsynchronousSocketChannel.open() uses the default group: http://download.java.net/java/jdk9/docs/api/java/nio/channels/AsynchronousSocketChannel.html#open-- But I am not sure if it leaves daemon threads if AsynchronousSocketChannel was not closed.
17-08-2016

At first, I didn't notice that Leaky.java runs in othervm mode. So even if this test doesn't shutdown a AsynchronousChannelGroup, it shouldn't affect other tests.
17-08-2016

This may be related to JDK-8158269, but unfortunately logs are not accessible any more to see full jstack output.
16-08-2016