I have simplified the reproducer slightly, no concurrency is needed. ``` // Reproducer for indy performance/classloading issue. // Run with JAVA_OPTS="-Xlog:class*=info" groovy test.groovy, // and observe a high volume of LambdaForm classes churning // even during steady state. def foo(Object x) { if (x.getClass().getName().equals("dummy")) print "dummy" } while (true) { foo("1") // 127 is just enough to trigger compilation of a new MethodHandle since // java.lang.invoke.MethodHandle.CUSTOMIZE_THRESHOLD defaults to 127. 127.times { foo(1) } } ```
It seems that every invocation where the argument types change causes IndyInterface to generate a brand new MethodHandle for the invocation. The LambdaForm compilation then happens when the new MethodHandle is used enough times to trigger customization. I think some of this was discussed in https://mail.openjdk.org/pipermail/mlvm-dev/2017-May/006760.html, but I don't fully understand how it applies to my case. 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.