[
https://hibernate.onjira.com/browse/HHH-5927?page=com.atlassian.jira.plug...
]
Steve Ebersole commented on HHH-5927:
-------------------------------------
Couple of things...
* @Andres, the branches from Strong and Sanne are based on 4.x, but you could still pull
their changes into a 3.6 fork. At least to verify that the changes have desired effect.
For example, I think the only real pertinent change on Sanne's in regard to this issue
is
https://github.com/Sanne/hibernate-orm/commit/4edca8e52bd4df34aadda98202d...
and that one should be pretty easy to backport to 3.6 using cherry-pick or diff/patching
* Regarding the {{synchonized}} on the {{get}} method, yes we could have gone with a more
granular re-entrant read/write lock. That code was added before the switch to Java 5 and
at that time we decided against pulling in the oswego library or others just to provide
that capability for that one usage. Now that the code bases on Java 6 we could certainly
look to change that using a java.util.concurrent.locks.ReentrantReadWriteLock. But I am
curious whether {{synchonized}} is the real bottleneck. Hard to say just from the
attached profile.
* Another option is to get out of writing and maintaining these classes altogether. Its
not a core competency of Hibernate as an O/RM solution. Overall this is my preferred
solution. There are a couple of options here.
*# Using the Google guava library has been suggested. The trouble there is that while
they do have "LRU" capability, it is strictly size based; and it is essentially
impossible for us to name an appropriate size for all deployments and probably just as
impossible expecting users to set that up correctly. See the
"semi-roll-our-own" point...
*# We could swap in something that is capable of completely replicating the functionality
of {{org.hibernate.internal.util.collections.SoftLimitMRUCache}}. Like I mentioned above,
guava currently does not fit this bill. Ideally we want that thing to be concurrent
(reentrant rather than synchronized) and GC-based. One library that seems to fit all
those reqs is
http://code.google.com/p/simplelrucache/ I have no experience/affiliation
with it.
*# We could do a semi-roll-our-own approach where we keep
{{org.hibernate.internal.util.collections.SoftLimitMRUCache}} but replace its innards with
stuff from guava,
http://code.google.com/p/concurrentlinkedhashmap/, etc
Performance risk: Suboptimal synchronization in
org.hibernate.engine.query.QueryPlanCache.getHQLQueryPlan
---------------------------------------------------------------------------------------------------------
Key: HHH-5927
URL:
https://hibernate.onjira.com/browse/HHH-5927
Project: Hibernate ORM
Issue Type: Improvement
Components: core
Reporter: Strong Liu
Assignee: Strong Liu
Attachments: hotspot.png
with Order Demo (real-life simulation attempt test app) I have noticed that there is
thread contention on createNamesQuery() which sounds suspicious.
After investigation it boils down to
org.hibernate.engine.query.QueryPlanCache.getHQLQueryPlan. It serves as a cache (internal,
not replacable) for queries using LRU algorithm (supplied from Apache utils).
Generally speaking, blocking threads in any sort of caches indicates a problem. From
about 2000 calls, 700 got blocked (which is also not nice for context switching).
I guess, one of the problems is that there is exclusive synchronization in get method:
public synchronized Object get(Object key) {...}
which could be replaced by a more granular read-write lock.
org/hibernate/engine/query/QueryPlanCache.java
org/hibernate/util/SoftLimitMRUCache.java
--
This message is automatically generated by JIRA.
For more information on JIRA, see:
http://www.atlassian.com/software/jira