You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@groovy.apache.org by "Joseph Athman (JIRA)" <ji...@apache.org> on 2017/08/25 17:55:00 UTC

[jira] [Updated] (GROOVY-8298) Slow Performance Caused by Invoke Dynamic

     [ https://issues.apache.org/jira/browse/GROOVY-8298?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Joseph Athman updated GROOVY-8298:
----------------------------------
    Description: 
I have been researching a problem my application is having where performance seems to be much slower than I would expect. After a lot of research I found GROOVY-6583 which seems to have the same symptoms (though not caused by the same method calls). After more research I found someone who reported a similar issue and created a [sample application|https://github.com/dwclark/deopt-storm] which reproduces the issue. I am seeing the same behavior he discusses which is that using the JIT probe I'm able to see that our production application is constantly uses a large amount of CPU on JIT activities for days on end, it never gets better. 

When doing a thread dump of our application we often see 20-50 threads all stuck on this same stack trace:


{code:none}
"qtp2078714399-360525": running, holding [771bcf60]
	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/1828868503.reinvoke(LambdaForm$BMH)
	at java.lang.invoke.LambdaForm$reinvoker/1917025677.dontInline(LambdaForm$reinvoker)
	at java.lang.invoke.LambdaForm$MH/462773420.guard(LambdaForm$MH)
	at java.lang.invoke.LambdaForm$MH/1947020920.linkToCallSite(LambdaForm$MH)
{code}


No matter how long the application runs it will continue to show this behavior. From what I've read I think our code causes this problem because we run code that looks like this:

{code:java}
// List of objects will consistent of 2-20 instances of classes 
// which all implement the same interface which defines the runMethod. 
// Each concrete implementation will have it's own unique behavior
def resultList = listOfObjects*.runMethod()
{code}

Turning off invoke dynamic compilation and using the regular groovy-all jar seems to eliminate the issue and result it overall better performance.

It would be nice if Groovy could at least identify this situation and prevent itself from getting in to the de-opt storm.


  was:
I have been researching a problem my application is having where performance seems to be much slower than I would expect. After a lot of research I found GROOVY-6583 which seems to have the same symptoms (though not caused by the same method calls). After more research I found someone who reported a similar issue and created a [sample application|https://github.com/dwclark/deopt-storm] which reproduces the issue. I am seeing the same behavior he discusses which is that using the JIT probe I'm able to see that our production application is constantly uses a large amount of CPU on JIT activities for days on end, it never gets better. 

When doing a thread dump of our application we often see 20-50 threads all stuck on this same stack trace:


{code:none}
"qtp2078714399-360525": running, holding [771bcf60]
	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/1828868503.reinvoke(LambdaForm$BMH)
	at java.lang.invoke.LambdaForm$reinvoker/1917025677.dontInline(LambdaForm$reinvoker)
	at java.lang.invoke.LambdaForm$MH/462773420.guard(LambdaForm$MH)
	at java.lang.invoke.LambdaForm$MH/1947020920.linkToCallSite(LambdaForm$MH)
{code}


No matter how long the application runs it will continue to show this behavior. From what I've read I think our code causes this problem because we run code that looks like this:

{code:java}
// List of objects will consistent of 2-20 instances of classes 
// which all implement the same interface which defines the runMethod. 
// Each concrete implementation will have it's own unique behavior
def resultList = listOfObjects*.runMethod()
{code}

It would be nice if Groovy could at least identify this situation and prevent itself from getting in to the de-opt storm.



> Slow Performance Caused by Invoke Dynamic
> -----------------------------------------
>
>                 Key: GROOVY-8298
>                 URL: https://issues.apache.org/jira/browse/GROOVY-8298
>             Project: Groovy
>          Issue Type: Bug
>    Affects Versions: 2.4.12
>            Reporter: Joseph Athman
>
> I have been researching a problem my application is having where performance seems to be much slower than I would expect. After a lot of research I found GROOVY-6583 which seems to have the same symptoms (though not caused by the same method calls). After more research I found someone who reported a similar issue and created a [sample application|https://github.com/dwclark/deopt-storm] which reproduces the issue. I am seeing the same behavior he discusses which is that using the JIT probe I'm able to see that our production application is constantly uses a large amount of CPU on JIT activities for days on end, it never gets better. 
> When doing a thread dump of our application we often see 20-50 threads all stuck on this same stack trace:
> {code:none}
> "qtp2078714399-360525": running, holding [771bcf60]
> 	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/1828868503.reinvoke(LambdaForm$BMH)
> 	at java.lang.invoke.LambdaForm$reinvoker/1917025677.dontInline(LambdaForm$reinvoker)
> 	at java.lang.invoke.LambdaForm$MH/462773420.guard(LambdaForm$MH)
> 	at java.lang.invoke.LambdaForm$MH/1947020920.linkToCallSite(LambdaForm$MH)
> {code}
> No matter how long the application runs it will continue to show this behavior. From what I've read I think our code causes this problem because we run code that looks like this:
> {code:java}
> // List of objects will consistent of 2-20 instances of classes 
> // which all implement the same interface which defines the runMethod. 
> // Each concrete implementation will have it's own unique behavior
> def resultList = listOfObjects*.runMethod()
> {code}
> Turning off invoke dynamic compilation and using the regular groovy-all jar seems to eliminate the issue and result it overall better performance.
> It would be nice if Groovy could at least identify this situation and prevent itself from getting in to the de-opt storm.



--
This message was sent by Atlassian JIRA
(v6.4.14#64029)