-
Bug
-
Resolution: Future Project
-
P4
-
None
-
21
-
generic
-
generic
A DESCRIPTION OF THE PROBLEM :
According to JEP 444, " if a virtual thread is blocked on, e.g., BlockingQueue.take(), and no other thread can obtain a reference to either the virtual thread or the queue, then the thread can be garbage collected — which is fine, since the virtual thread can never be interrupted or unblocked."
It does not work with default setting jdk.trackAllThreads=true, because virtual thread are stored in jdk.internal.vm.ThreadContainers.RootContainer.TrackingRootContainer#VTHREADS
The problem was not exist by default before in https://bugs.openjdk.org/browse/JDK-8302185 jdk.trackAllThreads was enabled by default
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Start example code and take heap dump
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Virtual thread is eligible for garbage collection
ACTUAL -
Virtual thread is accessible from GC root:
io.Demo$AAAConsumer 0x604610278 16 B
val$task of java.lang.VirtualThread$VThreadContinuation$1 0x604616bd8 40 B
target of java.lang.VirtualThread$VThreadContinuation 0x604616b38 120 B
cont of java.lang.VirtualThread 0x604616668 280 B
key of java.util.concurrent.ConcurrentHashMap$Node 0x604617200 32 B
java.util.concurrent.ConcurrentHashMap$Node[16] 0x6046171b0 112 B
table of java.util.concurrent.ConcurrentHashMap 0x604614828 176 B
map of java.util.concurrent.ConcurrentHashMap$KeySetView 0x604614810 200 B
VTHREADS of jdk.internal.vm.ThreadContainers$RootContainer$TrackingRootContainer, GC Root: Sticky class 0x604614770 312 B
---------- BEGIN SOURCE ----------
package io;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.TimeUnit;
public class Demo {
public static void main(String[] args) throws InterruptedException {
Thread.ofVirtual().start(new AAAConsumer());
// here I catch thread/heap dump
TimeUnit.SECONDS.sleep(15);
}
static class AAAConsumer implements Runnable {
@Override
public void run() {
try {
new ArrayBlockingQueue<>(100).take();
} catch (InterruptedException e) {
System.out.println("AAAConsumer interrupted");
}
}
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
-Djdk.trackAllThreads=false
FREQUENCY : always
According to JEP 444, " if a virtual thread is blocked on, e.g., BlockingQueue.take(), and no other thread can obtain a reference to either the virtual thread or the queue, then the thread can be garbage collected — which is fine, since the virtual thread can never be interrupted or unblocked."
It does not work with default setting jdk.trackAllThreads=true, because virtual thread are stored in jdk.internal.vm.ThreadContainers.RootContainer.TrackingRootContainer#VTHREADS
The problem was not exist by default before in https://bugs.openjdk.org/browse/JDK-8302185 jdk.trackAllThreads was enabled by default
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Start example code and take heap dump
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Virtual thread is eligible for garbage collection
ACTUAL -
Virtual thread is accessible from GC root:
io.Demo$AAAConsumer 0x604610278 16 B
val$task of java.lang.VirtualThread$VThreadContinuation$1 0x604616bd8 40 B
target of java.lang.VirtualThread$VThreadContinuation 0x604616b38 120 B
cont of java.lang.VirtualThread 0x604616668 280 B
key of java.util.concurrent.ConcurrentHashMap$Node 0x604617200 32 B
java.util.concurrent.ConcurrentHashMap$Node[16] 0x6046171b0 112 B
table of java.util.concurrent.ConcurrentHashMap 0x604614828 176 B
map of java.util.concurrent.ConcurrentHashMap$KeySetView 0x604614810 200 B
VTHREADS of jdk.internal.vm.ThreadContainers$RootContainer$TrackingRootContainer, GC Root: Sticky class 0x604614770 312 B
---------- BEGIN SOURCE ----------
package io;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.TimeUnit;
public class Demo {
public static void main(String[] args) throws InterruptedException {
Thread.ofVirtual().start(new AAAConsumer());
// here I catch thread/heap dump
TimeUnit.SECONDS.sleep(15);
}
static class AAAConsumer implements Runnable {
@Override
public void run() {
try {
new ArrayBlockingQueue<>(100).take();
} catch (InterruptedException e) {
System.out.println("AAAConsumer interrupted");
}
}
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
-Djdk.trackAllThreads=false
FREQUENCY : always
- relates to
-
JDK-8302185 jdk.trackAllThreads should be enabled by default
- Closed