I'm struggling to determine what is causing a moderately large Groovy application to perform slowly in production. When taking thread dumps of running applications the strange thing I'm seeing is lots of threads with a stacktrace like this:
at java.lang.invoke.MethodHandleNatives.setCallSiteTargetNormal(Native Method)
at java.lang.invoke.CallSite.setTargetNormal(CallSite.java:258)
at java.lang.invoke.MutableCallSite.setTarget(MutableCallSite.java:154)
at org.codehaus.groovy.vmplugin.v7.Selector$MethodSelector.doCallSiteTargetSet(Selector.java:909)
at org.codehaus.groovy.vmplugin.v7.Selector$MethodSelector.setCallSiteTarget(Selector.java:969)
at org.codehaus.groovy.vmplugin.v7.IndyInterface.selectMethod(IndyInterface.java:228)
at java.lang.invoke.LambdaForm$DMH/1665404403.invokeStatic_L3IL5_L(LambdaForm$DMH)
at java.lang.invoke.LambdaForm$BMH/1705072168.reinvoke(LambdaForm$BMH)
I've seen some mentions online that the setCallSiteTargetNormal
method is rather heavyweight and blocks all JVM threads while it is invoked. We use Groovy's invoke dynamic support and I'm wondering if we are hitting some kind of bug in Groovy which is causing this method to be called too extensively.
Obvious performance issues I've already checked:
- Memory usage is fine
- GC overhead is normal
- CPU usage on the server looks ok
- External DB and web service calls are all normal
One note about CPU usage is that the app is behaving like it is starved for CPU, but it only is using about about 1/4 of the total CPU of a 4 CPU machine. It is acting like a thread should be pegging a CPU a 100%, but I'm not seeing that at all. However some information I've found online points to the setCallSiTeTargetNormal
method call as being something that completely blocks all threads on the JVM.