The changes in JDK-8319662 seem to have had an unintended side-effect. If you create a short-lived virtual thread, followed by a second, when the pool worker thread waits for its next task, it doesn't wait for anywhere near the keep-alive time, but instead keepAlive/parallelism based on this code:
if (quiet) { // use timeout if trimmable
int nt = (short)(qc >>> TC_SHIFT);
long delay = keepAlive; // scale if not at target
if (nt != (nt = Math.max(nt, parallelism)) && nt > 0)
delay = Math.max(TIMEOUT_SLOP, delay / nt);
if ((deadline = delay + System.currentTimeMillis()) == 0L)
deadline = 1L; // avoid zero
}
On my system with a parallelism of 16, the work thread times out and terminates after 1875ms instead of the expected keep-alive of 30 seconds (30000/16 = 1875).
This was detected via test/hotspot/jtreg/serviceability/jvmti/GetOwnedMonitorInfo/GetOwnedMonitorInfoTest.java - see JDK-8327743. I instrumented the test and FJP:
TEST: Virtual-Worker-Thread-0 is terminating at 1710894777172
TEST: Virtual-Worker-Thread-1 is terminating at 1710894778215
DEBUG: ForkJoinPool-1-worker-1 is terminating at 1710894780090 <= 1875ms after vthread terminated