<div dir="ltr">Hi Alan,<div>Thanks for the second EA of new object monitor implementation. I have been testing it for the last few days.</div><div><br></div><div>I am happy to confirm the hanging is not happening anymore on my side. I also observed improvements on receiving "jdk.VirtualThreadPineed" events.</div><div>In my setup I only get "jdk.VirtualThreadPineed" events in Classloading scenarios or object.wait() within synchronized blocks which are expected as far as I know.</div><div><br></div><div>I have been testing only with LockingMode=1 (default) for now. I will test LockingMode=2 and let you know if any issues come up.</div><div><br></div><div>My current setup is heavily using synchronized blocks (lots of caches) and lots of concurrent class loadings, as well as object.wait() in few of the application's hot paths. </div><div>So far, hanging hasn't been observed which is really good news. Congratulations to you and the team.</div><div><br></div><div>I was triggered by your explanation about how new implementation tries to avoid hanging by calling a chosen successor upon exiting synchronized block and tried to check performance of new build against</div><div>virtual thread impl in 21 and also platform threads in current build. This is the sample code:</div><div><br></div><div>public class VirtualThreadPerformanceTest {<br><br>    public static void main(String[] args) throws InterruptedException {<br>        int size = 1000;<br>        test(false, size);<br>        test(true, size);<br>    }<br><br>    private static void test(boolean isVirtual, int size) throws InterruptedException {<br>        ExecutorService executorService = isVirtual == true ? Executors.newVirtualThreadPerTaskExecutor()<br>            : Executors.newThreadPerTaskExecutor(Thread.ofPlatform().factory());<br>        CountDownLatch latch = new CountDownLatch(size);<br>        long start = System.currentTimeMillis();<br>        Object object = new Object();<br>        for (int i = 0; i < size; i++) {<br>            executorService.submit(() -> {<br>                synchronized (object) {<br>                    try {<br>                        object.wait(100);<br>                    } catch (InterruptedException e) {<br>                        //do nothing;<br>                    }<br>                }<br>                latch.countDown();<br>            });<br>        }<br>        synchronized (object) {<br>            object.notifyAll();<br>        }<br>        latch.await();<br>        long duration = System.currentTimeMillis() - start;<br>        System.out.println((isVirtual? "Virtual" : "Platform") + " took " + duration + " milliseconds");<br>    }<br>}<br></div><div><br></div><div>To my surprise, Virtual thread is significantly slower than platform thread here. 4x-5x. And also virtual thread on new build is consistently slower than java 21 in this scenario, around 100-200 milliseconds in above example which is significant. Is this already known and expected? Would you please provide some insights on what is happening here?</div><div><br></div><div>And also on the classloader side, I was wondering if there are some plans to change classloader implementation (i.e to use a Reentrantlock per class rather than synchronizing on an object per class) </div><div>or do you expect the limitation of having native frames on the stack causing thread pinning goes away rather soon and hence no need to change classloader impl?</div><div><br></div><div>Kind regards,</div><div>Masoud</div><div><br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, Feb 22, 2024 at 1:09 PM Alan Bateman <<a href="mailto:Alan.Bateman@oracle.com">Alan.Bateman@oracle.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">On 21/02/2024 10:49, masoud parvari wrote:<br>
> :<br>
><br>
> And of course I am aware of Spring Boot 3.2+ releases. The point of my <br>
> load testing was testing an application with lots of contention on <br>
> objectmonitors rather than a setup where most of the synchronized <br>
> blocks have been replaced by ReentrantLock.<br>
><br>
> So I would argue that for the mere purpose of testing Loom's new <br>
> object monitor implementation, and making sure hanging is not <br>
> happening, Spring boot 2.7.x is a better candidate than 3.2.x. I hope <br>
> this helps to clarify the testing's goal.<br>
><br>
<br>
I'm not familiar with the different versions of Spring but it sounds <br>
like the 2.7.x has more uses of object monitors. That is useful to know.<br>
<br>
Note that the EA builds have been refreshed to pick up recent changes <br>
(and changes from main line). There is a change to the object monitor <br>
implementation that makes blocked threads that are pinned compete with <br>
the chosen successor when some thread exits a monitor. That should help <br>
with some of the cases where resolving class references is calling <br>
through the VM to load classes. Also one of your mails mentioned that <br>
your JFR recordings didn't have all the expected jdk.VirtualThreadPinned <br>
events. There are three cases where jdk.VirtualThreadPinned is recorded, <br>
one of these missed the first EA build.<br>
<br>
-Alan<br>
</blockquote></div>