Profiling of our application has shown that under high load (high concurrency) the most significant, non-database related, performance hot spot is the GetMergedObjectDefinition() method in Spring.Objects.Factory.Support.AbstractObjectFactory. The Spring.Collections.SynchronizedHashtable type used to cache merged object definitions scales very poorly for many readers as any access to the collection is serialized using a lock block.
Furthermore, the actual object definition construction also happens in a lock block (in the GetMergedObjectDefinitionInternal method). I'm not sure if this is really necessary; unless the object definition creation actually involves some kind of registration type logic it should be fine to create the definition and then enter the synchronized area to add the object to the cache only to discard it if it has already been added and instead grab the one the is now in the cache.
In .Net 4 or later a possible and very straightforward improvement would be to use a System.Collection.Concurrent.ConcurrentDictionary instead, assuming it is okay to construct the merged definitions outside the locks. In .Net 3.5 a possible improvement would be to protect the cache with a System.Threading.ReaderWriterLockSlim and, preferably, construct the object definitions while holding no locks. This would be very similar to the fix I provided for
I feel that I don't really have the required overview of the Spring source code to analyze this issue fully so I'm not sure at all if my suggestions are feasible. I think this might mainly be a problem when non-application scoped objects are used. However, it ismy opinion that the coarse grained synchronization used in the SynchronizedHashtable implementation should be used very carefully.