<div dir="auto">FYI I have have already share some of these things with some loom dev at <a href="https://github.com/async-profiler/async-profiler/issues/779">https://github.com/async-profiler/async-profiler/issues/779</a></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">Il lun 21 ago 2023, 12:00 Gillespie, Oli <<a href="mailto:ogillesp@amazon.co.uk">ogillesp@amazon.co.uk</a>> ha scritto:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi,<br>
<br>
I've been using virtual threads and I noticed some apparently significant overhead in SharedRuntime::handle_wrong_method.<br>
<br>
A simple 'benchmark'/stress test profiled with async-profiler shows (among other similar stacks):<br>
<br>
```<br>
--- 29055613704 ns (21.14%), 288804 samples<br>
[ 0] ImmutableOopMap::update_register_map(frame const*, RegisterMap*) const<br>
[ 1] vframeStream::vframeStream(JavaThread*, bool, bool, bool)<br>
[ 2] SharedRuntime::find_callee_method(JavaThread*)<br>
[ 3] SharedRuntime::reresolve_call_site(JavaThread*)<br>
[ 4] SharedRuntime::handle_wrong_method(JavaThread*)<br>
[ 5] jdk.internal.vm.Continuation.enterSpecial<br>
[ 6] jdk.internal.vm.Continuation.run<br>
[ 7] java.lang.VirtualThread.runContinuation<br>
[ 8] java.lang.VirtualThread$$Lambda.0x00007ffad006e3d8.run<br>
[ 9] java.util.concurrent.ForkJoinTask$RunnableExecuteAction.exec<br>
[10] java.util.concurrent.ForkJoinTask.doExec<br>
[11] java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec<br>
[12] java.util.concurrent.ForkJoinPool.scan<br>
[13] java.util.concurrent.ForkJoinPool.runWorker<br>
[14] java.util.concurrent.ForkJoinWorkerThread.run<br>
```<br>
<br>
Is this just the expected path+cost of swapping between virtual threads, or is there something surprising happening here?<br>
<br>
My code for the test is:<br>
<br>
```<br>
import java.util.concurrent.*;<br>
<br>
public class Virt {<br>
public static void main(String[] args) throws Exception {<br>
while (true) {<br>
ExecutorService e = Executors.newVirtualThreadPerTaskExecutor();<br>
for (int i = 0; i < 100_000; i++) e.submit(Main::task);<br>
e.shutdown(); e.awaitTermination(100, TimeUnit.MINUTES);<br>
}<br>
}<br>
static void task() { }<br>
}<br>
```<br>
<br>
Notes:<br>
- I'm running with JDK21, using `java -XX:+UnlockExperimentalVMOptions -XX:-DoJVMTIVirtualThreadTransitions Virt.java` since I know async-profiler as a JVMTI agent triggers some other overheads which would be distracting in the profiling data.<br>
- Another user saw similar behaviour in <a href="https://github.com/async-profiler/async-profiler/issues/779#issuecomment-1651225252" rel="noreferrer noreferrer" target="_blank">https://github.com/async-profiler/async-profiler/issues/779#issuecomment-1651225252</a>.<br>
<br>
Apologies if this is just totally expected behaviour, but I couldn't find any discussion on it.<br>
<br>
Regards,<br>
<br>
Oli<br>
<br>
<br>
<br>
Amazon Development Centre (London) Ltd. Registered in England and Wales with registration number 04543232 with its registered office at 1 Principal Place, Worship Street, London EC2A 2FA, United Kingdom.<br>
<br>
<br>
<br>
</blockquote></div>