Dead Continuation cause resource leak?

Ron Pressler ron.pressler at oracle.com
Thu May 28 10:08:31 UTC 2020


A continuation, or a virtual thread for that matter, that becomes unreachable before termination
corresponds to an ordinary platform thread that sleeps forever. Neither the JDK nor the OS makes
liveness guarantees about code.

Having said that, a virtual thread can become unreachable before termination only due to a serious
bug. When it is mounted, a reference to it is held by the scheduler or else it would be able to schedule
it, and when blocked (and unmounted) a reference to it is held by the blocking construct, or else
it would never be able to unblock it.

— Ron


On 28 May 2020 at 07:43:09, 施慧 (kalinshi at qq.com) wrote:

Hi All,  


Trying to understand Loom continuation implementation. In following LeakTest,  Continuation Object is unreachable after first yield, but its runnable target is not finished yet.  
There might be some resources allcoated during continuation run (native memory in this test case and free in finally block --- not cleaner way), when continuation object is collected, these resources are not closed or freed.  


Is it possible to "clean up" a dead continuation which is not finished yet but collecting by GC?   


Tested with code cloned from github today.  
javac --add-exports java.base/jdk.internal.ref=ALL-UNNAMED --add-exports java.base/jdk.internal.misc=ALL-UNNAMED  LeakTest.java  
java --add-exports java.base/jdk.internal.ref=ALL-UNNAMED --add-exports java.base/jdk.internal.misc=ALL-UNNAMED  LeakTest  
clean continuation  



import jdk.internal.ref.Cleaner;  
import jdk.internal.misc.Unsafe;  
public class LeakTest {  
    private static final Unsafe unsafe = Unsafe.getUnsafe();  
    static ContinuationScope scope = new ContinuationScope("scope");  
    public static void main(String[] args) throws Exception {  
        bar();  
        System.gc();  
        Thread.sleep(1000);  
        System.gc();  
        Thread.sleep(1000);  
    }  


    public static void bar() {  
        Continuation cont = new Continuation(scope, () -> {  
            long mem = 0;  
            try {  
                // open file/socket  
                mem = unsafe.allocateMemory(100);  
                Continuation.yield(scope);  
            } finally {  
                unsafe.freeMemory(mem);  
                System.out.println("release memory");  
            }  
        });  
        Cleaner.create(cont, () -> { System.out.println("clean continuation");  });  
        cont.run();  
        //cont.run();  
    }  
}  



Regards


More information about the loom-dev mailing list