[
http://opensource.atlassian.com/projects/hibernate/browse/HHH-2645?page=c...
]
Steve Ebersole commented on HHH-2645:
-------------------------------------
I took this maptest.patch stuff, modified it slighty and added timings for jdk5
ConcurrentHashMap also (just to see). I get slightly different results:
baseline : 9051 ms
FastHashMap : 8499 ms (ratio=0.9390123)
ConcurrentHashMap (jdk) : 509 ms (ratio=0.05623688)
ConcurrentHashMap (dl) : 6380 ms (ratio=0.7048945)
ConcurrentReaderHashMap (dl) : 3544 ms (ratio=0.39155895)
To be completely happy, I'd still want to average a couple of 'liveRun'
executions together rather than relying on one. I already added "forceful GC"
code to attempt to isolate the tests from GC from other tests. That would be all I could
think of to get the best results...
From my numbers, the JDK ConcurrentHashMap is clearly the best option,
but unfortunately not available as a solution until 4.0 when we move to jdk5. Other than
that, the Doug Lea / Oswego ConcurrentReaderHashMap seemed to significantly beat the
others for this access pattern.
Synchronization bottleneck in EntityModeToTuplizerMapping
---------------------------------------------------------
Key: HHH-2645
URL:
http://opensource.atlassian.com/projects/hibernate/browse/HHH-2645
Project: Hibernate3
Issue Type: Patch
Components: core
Affects Versions: 3.2.3, 3.2.4, 3.2.4.sp1
Environment: Hibernate 3.2.3 (and later), Sun's JDK 1.4.2_12 (server VM) on
SunOS 5.10, Oracle 10g R2
Reporter: Erik Bergersjö
Assignee: Gail Badner
Priority: Minor
Attachments: concurrentreader.patch, maptest.patch
We have had a major performance bottleneck in EntityModeToTuplizerMapping with Hibernate
version 3.2.3 and the code for that class in 3.2.4sp1 is unchanged. We have found a
solution that solves the issue and would like to get it into the real version. I submitted
to the user forum first and was asked to create a JIRA issue.
The problematic line is:
private final Map tuplizers = Collections.synchronizedMap( new SequencedHashMap() );
We have changed it to (using util.concurrent):
private final Map tuplizers = new
EDU.oswego.cs.dl.util.concurrent.ConcurrentReaderHashMap();
This change alone makes our use cases six times faster. The difference is that
ConcurrentReaderHashMap handles concurrent readers much better, they don't have to
wait for each other.
The problem occurs when a high number of threads try to initialize sets (see mapping
below). A thread dump showed a high number of threads waiting for the same monitor, see
partial stack trace below.
The code runs on Sun's JDK 1.4.2_12 (server VM) on SunOS 5.10 and the kernel spends a
lot of time handling mutexes with the original implementation. That time disappears from
the radar screen with the fixed version.
Example mapping for set:
[code]
<set name="lines" lazy="true" inverse="true"
cascade="all-delete-orphan">
<key>
<column name="col1" not-null="true" />
<column name="col2" not-null="true" />
</key>
<one-to-many class="LineClass" />
</set>
[/code]
Stack trace (partial):
"Thread-108" prio=5 tid=0x05852e90 nid=0x103 waiting for monitor entry
[0x3ed7e000..0x3ed7fc28]
at java.util.Collections$SynchronizedMap.get(Collections.java:1942)
- waiting to lock <0x89d30788> (a java.util.Collections$SynchronizedMap)
at
org.hibernate.tuple.EntityModeToTuplizerMapping.getTuplizerOrNull(EntityModeToTuplizerMapping.java:53)
at
org.hibernate.tuple.EntityModeToTuplizerMapping.getTuplizer(EntityModeToTuplizerMapping.java:66)
at org.hibernate.type.ComponentType.getPropertyValues(ComponentType.java:353)
at org.hibernate.type.ComponentType.isEqual(ComponentType.java:141)
at org.hibernate.engine.CollectionKey.equals(CollectionKey.java:50)
at java.util.HashMap.eq(HashMap.java:274)
at java.util.HashMap.get(HashMap.java:323)
at
org.hibernate.engine.loading.CollectionLoadContext.getLocalLoadingCollectionEntry(CollectionLoadContext.java:163)
at
org.hibernate.engine.loading.CollectionLoadContext.locateLoadingCollectionEntry(CollectionLoadContext.java:150)
at
org.hibernate.engine.loading.CollectionLoadContext.getLoadingCollection(CollectionLoadContext.java:92)
at org.hibernate.loader.Loader.readCollectionElement(Loader.java:1003)
at org.hibernate.loader.Loader.readCollectionElements(Loader.java:646)
at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:591)
at org.hibernate.loader.Loader.doQuery(Loader.java:701)
at
org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:236)
at org.hibernate.loader.Loader.loadCollection(Loader.java:1994)
at
org.hibernate.loader.collection.CollectionLoader.initialize(CollectionLoader.java:36)
at
org.hibernate.persister.collection.AbstractCollectionPersister.initialize(AbstractCollectionPersister.java:565)
at
org.hibernate.event.def.DefaultInitializeCollectionEventListener.onInitializeCollection(DefaultInitializeCollectionEventListener.java:60)
at org.hibernate.impl.SessionImpl.initializeCollection(SessionImpl.java:1716)
at
org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:344)
at
org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:86)
at org.hibernate.collection.PersistentSet.iterator(PersistentSet.java:163)
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
http://opensource.atlassian.com/projects/hibernate/secure/Administrators....
-
For more information on JIRA, see:
http://www.atlassian.com/software/jira