Issue 1:
Patrick Linskey opened SPR-9748 and commented

RequestMappingHandlerAdapter creates a new HandlerMethod for each request. HandlerMethods cache their MethodParameters to avoid costly reflection calls each time annotation stats are needed, but the per-request copy circumvents this cache. This patch explicitly copies the MethodParameter cache from a HandlerMethod and its request-scoped dependents.

Affects: 3.1.1, 3.1.2, 3.2 M2

Issue Links:

#13936 monitor contention at org.springframework.core.MethodParameter.getParameterAnnotations() ("is duplicated by")

#17058 NPE in org.springframework.core.MethodParameter.getParameterName (possible race condition)

#17429 Thread contention in HandlerMethod due to unnecessary BeanFactory.getType call

Referenced from: commits 2295372, 0a877af

1 votes, 3 watchers

Issue 2:
mck opened SPR-7949 and commented

Under high-concurrent load situation, in an application using many prototype beans, contention occurs in DefaultSingletonBeanRegistry.getSingletonNames(..)

This method has uses singletonObjects as a mutex for all map operations.

Using a ReadWriteLock this contention could be removed, as in our case 99% of the calls here are read-only.

We see hundreds of thread dumps like in a single jvm:

java.lang.Thread.State: BLOCKED (on object monitor)

at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:180)

waiting to lock <0x00007fb8519b11b0> (a java.util.concurrent.ConcurrentHashMap)

at org.springframework.beans.factory.support.AbstractBeanFactory.isTypeMatch(AbstractBeanFactory.java:452)

at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanNamesForType(DefaultListableBeanFactory.java:317)

at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanNamesForType(DefaultListableBeanFactory.java:296)

at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:250)

at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1083)

java.lang.Thread.State: BLOCKED (on object monitor)

at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingletonNames(DefaultSingletonBeanRegistry.java:277)

waiting to lock <0x00007fb856ab64d8> (a java.util.concurrent.ConcurrentHashMap)

at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanNamesForType(DefaultListableBeanFactory.java:352)

at org.springframework.beans.factory.BeanFactoryUtils.beanNamesForTypeIncludingAncestors(BeanFactoryUtils.java:185)

at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:829)

at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:744)

at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:703)

at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.resolvedCachedArgument(AutowiredAnnotationBeanPostProcessor.java:436)

at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.access$0(AutowiredAnnotationBeanPostProcessor.java:432)

at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:469)

at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:84)

at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:283)

at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1074)

at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireBean(AbstractAutowireCapableBeanFactory.java:295)

java.lang.Thread.State: BLOCKED (on object monitor)

at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:180)

waiting to lock <0x00007fb8519b11b0> (a java.util.concurrent.ConcurrentHashMap)

at org.springframework.beans.factory.support.AbstractBeanFactory.isTypeMatch(AbstractBeanFactory.java:452)

at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanNamesForType(DefaultListableBeanFactory.java:317)

at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanNamesForType(DefaultListableBeanFactory.java:296)

at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:250)

at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1083)

Affects: 3.0.4, 3.0.5

Attachments:

SPR-7949.patch (15.19 kB)

Issue Links:

#11536 Cache by-type lookups in DefaultListableBeanFactory ("duplicates")

#13828 Threads blocking on getSingleton method on DefaultSingletonBeanRegistry class ("is duplicated by")

17 votes, 16 watchers