You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@groovy.apache.org by "Ken Lam (JIRA)" <ji...@apache.org> on 2018/02/05 08:16:00 UTC

[jira] [Commented] (GROOVY-5249) Avoid unnecessary locking in ClassInfo.getMetaClass

    [ https://issues.apache.org/jira/browse/GROOVY-5249?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16352124#comment-16352124 ] 

Ken Lam commented on GROOVY-5249:
---------------------------------

 Is it possible to back port the following 5 revisions to Groovy 1.7.5?

SHA-1: 3893a91dd3cdd4fdbcb873d1359f6479ef570e1a

SHA-1: f78a90de0512c37ff09d417a549723596a862288

SHA-1: 937cd2d9c0bc537e1b16614cae42a416c6ae8f31

SHA-1: 0938de11c6b2661d891f6bb9c8d67cd372f9b869

SHA-1: c7c7ed6784a349f1e6180c97c0658a40141763b3

 

All these revisions only modify this file:

src\main\org\codehaus\groovy\reflection\ClassInfo.java

 

Can I do it safely and rebuild the jar for use in Grails 1.3.5?

> Avoid unnecessary locking in ClassInfo.getMetaClass
> ---------------------------------------------------
>
>                 Key: GROOVY-5249
>                 URL: https://issues.apache.org/jira/browse/GROOVY-5249
>             Project: Groovy
>          Issue Type: Bug
>          Components: groovy-runtime
>         Environment: Linux 64-bit, Java 1.6, Tomcat, Grails
>            Reporter: Serge P. Nekoval
>            Assignee: Jochen Theodorou
>            Priority: Critical
>             Fix For: 2.3.0-beta-1, 2.2.3
>
>         Attachments: mc.patch, mc.patch
>
>
> We have a Grails application serving hundreds of requests per second and this seems to be the most critical hot spot for us. Under high load, most threads are blocked in the following call stack:
> {code}
> "http-apr-8080"-exec-144
> sun.misc.Unsafe.park(Native Method)
> java.util.concurrent.locks.LockSupport.park(LockSupport.java:158)
> java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:811)
> java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:842)
> java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1178)
> org.codehaus.groovy.util.LockableObject.lock(LockableObject.java:34)
> org.codehaus.groovy.reflection.ClassInfo.lock(ClassInfo.java:268)
> org.codehaus.groovy.reflection.ClassInfo.getMetaClass(ClassInfo.java:193)
> org.codehaus.groovy.runtime.metaclass.MetaClassRegistryImpl.getMetaClass(MetaClassRegistryImpl.java:214)
> org.codehaus.groovy.runtime.InvokerHelper.getMetaClass(InvokerHelper.java:747)
> org.codehaus.groovy.runtime.InvokerHelper.invokePojoMethod(InvokerHelper.java:780)
> org.codehaus.groovy.runtime.InvokerHelper.invokeMethod(InvokerHelper.java:772)
> org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation.castToBoolean(DefaultTypeTransformation.java:156)
> org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation.booleanUnbox(DefaultTypeTransformation.java:65)
> {code}
> Grails uses {{InvokerHelper}} a lot, which calls {{ClassInfo.getMetaClass}} which uses locking. This is stop-the-world lock affecting all threads (they all hit the same {{ClassInfo}} instance). Note that 99,999% of time the locking is useless as nothing is modified (typically all metaclasses getting modified on startup). 
> There are several related tickets: GROOVY-3557 and GROOVY-5059, not really solving the issue.
> The solution could be to use more fine-grained locks (ReadWriteLock) or Atomics. Should be easy to implement, but need to isolate modification part from read-only parts.
> Doing so can be a good boost to overall Grails performance.



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)