Synchronization bottleneck in EntityModeToTuplizerMapping

Description

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)

Environment

Hibernate 3.2.3 (and later), Sun's JDK 1.4.2_12 (server VM) on SunOS 5.10, Oracle 10g R2

Activity

Show:
PaulP
February 12, 2008, 7:59 AM

This issue appears to be fixed in core/tags/v326, but doesn't show in the 3.2.6 release notes (I assume because this issue doesn't have a 'fix version'). Might want to amend that?

Steve Ebersole
February 12, 2008, 4:01 PM

setting fixed version

Steve Ebersole
May 21, 2010, 9:38 PM
Edited

Just wanted to point out that this has been fixed on trunk which will become 3.6 because we moved to jdk 1.5 there as minimum.

  • by "this" I mean

Steve Ebersole
March 21, 2011, 7:09 PM

Bulk closing stale resolved issues

Chiting Huang
June 22, 2016, 2:38 AM

Excuse me,

This issue has been fixed in the 3.6.10.Final?
Our system has performance issue with longer operation(slower and slower).

Assignee

Gail Badner

Reporter

Erik Bergersjö

Fix versions

Labels

None

backPortable

None

Suitable for new contributors

None

Requires Release Note

None

Pull Request

None

backportDecision

None

Components

Affects versions

Priority

Minor
Configure