Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

XmlBeanDefinitionReader runs 10x slower due to resetBeanDefinition check [SPR-8318] #12966

Closed
spring-issuemaster opened this issue May 9, 2011 · 7 comments

Comments

@spring-issuemaster
Copy link
Collaborator

@spring-issuemaster spring-issuemaster commented May 9, 2011

Matt McQuarrie opened SPR-8318 and commented

When trying to load 700+ beans using:
org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions

it takes over 5 min using the 2.5.3 (or 3.0.5) library, but only 24 sec using the 2.0.4 library. This seems to only occur on the AIX JVM.

Please see the attached zip with example scripts loadbeans256.sh and loadbeans204.sh

We have also tested with spring 3.0.5 and the results are similar to 2.5.6.

Thanks for your help with this. This is the first time I've filed a defect so please let me know if I'm missing anything.

  • Matt

Affects: 2.5.6, 3.0.5

Attachments:

Backported to: 3.2.11

1 votes, 6 watchers

@spring-issuemaster
Copy link
Collaborator Author

@spring-issuemaster spring-issuemaster commented May 10, 2011

Matt McQuarrie commented

After further testing this issue seems to occur on all JVMs. HotSpot, JRockit, and IBM's JVM seem to have this issue with varying severities. For example, HotSpot takes 10x longer to load the example project's beans while IBM's JVM takes 20x longer.

@spring-issuemaster
Copy link
Collaborator Author

@spring-issuemaster spring-issuemaster commented May 18, 2011

Jonathan Keller commented

Adding some more information on this one:

I also just did a little research into the startup time problem of KFS and the difference between Spring 2.0.4 and 2.5.6. The problem comes partially in that we have almost 100,000 beans defined between all our XML files, not counting those which are in the Rice jars. But more than that is some code that Spring added by 2.5.6 which is intended to improve the handling of parent beans. (They seemed to be working before, so I don't know what changed that made this necessary.)

The problem is a new line at the end of the registerBeanDefinition() method:

resetBeanDefinition(beanName);

This method is designed to find any beans for which the current bean is a parent and "reset" the definition in order to ensure that the proper values are being inherited. This unfortunately requires iterating over all beans previously defined. In the selection of the parsing I traced below, which processed about 6,000 bean definitions, there were almost 17,000,000 retrievals of beans simply to check if the current bean was its parent. This method is recursive, so if there is a parent, then it does the iteration all over again.

So, it seems that the more beans which use the inheritance which makes Spring so useful, the more we impact performance. It seems to be that a fix for this would be for Spring to index the beans by their parents (another HashMap?) so such extensive iteration would not be necessary. It seems it would be fairly easy to update this method (and a couple others) to maintain/check this new cache to greatly reduce the application startup time.

@spring-issuemaster
Copy link
Collaborator Author

@spring-issuemaster spring-issuemaster commented May 18, 2011

Jonathan Keller commented

I'm attaching a diff file containing the changes I made locally to the DefaultListableBeanFactory class to implement a possible solution. This did immediately decrease the time needed to process all our beans.

It seems to work for the use case which we have for Spring. I don't know if there are other edge cases that may exist for which it could break, but it may be a start.

Thanks.

diff DefaultListableBeanFactory-original-spring-2.5.6.txt DefaultListableBeanFactory.java -b -u

@spring-issuemaster
Copy link
Collaborator Author

@spring-issuemaster spring-issuemaster commented Jun 1, 2011

John Walker commented

VM Ware has requested to become a Commercial Affliate for Kuali Open Source. It would be helpful to the Kuali Community if someone at VMWare/Spring could address the slowness problem experienced/witnessed between versions 2.0.4 and 2.5.6. Thanks.

@spring-issuemaster
Copy link
Collaborator Author

@spring-issuemaster spring-issuemaster commented Jul 14, 2014

Kristina Taylor commented

Kuali Rice has recently done a Spring 4.0.5 upgrade but is still experiencing this problem. We verified that the patch submitted by Jonathan Keller, when merged with the Spring 4.0.5 version, brings our times back to normal from the 10x slowdown we were experiencing. Please reconsider applying this patch as it is a pretty major issue with performance.

@spring-issuemaster
Copy link
Collaborator Author

@spring-issuemaster spring-issuemaster commented Jul 14, 2014

Juergen Hoeller commented

Sorry that this issue remained unnoticed for so long... We'll pick it up again now for the 4.1 RC phase, with backports possibly following.

Juergen

@spring-issuemaster
Copy link
Collaborator Author

@spring-issuemaster spring-issuemaster commented Jul 15, 2014

Juergen Hoeller commented

I've optimized registerBeanDefinition to only call resetBeanDefinition in case of a pre-existing bean definition or a pre-existing singleton instance. This means that resetBeanDefinition won't be called at all for regular early bean definition registration phases (such as with XML file parsing).

Introducing a parent-children association cache would be an option as well but requires clean management of both ends of that association, i.e. if a parent gets removed or one of the children gets removed... That didn't seem to be worth it, if the 90% case can be addressed as above.

Juergen

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
2 participants
You can’t perform that action at this time.