]
Steve Ebersole closed HHH-1328.
-------------------------------
Closing stale resolved issues
org.hibernate.util.SimpleMRUCache keeps a soft reference to the cache
key, so cached values get collected prematurely
---------------------------------------------------------------------------------------------------------------------
Key: HHH-1328
URL:
http://opensource.atlassian.com/projects/hibernate/browse/HHH-1328
Project: Hibernate Core
Issue Type: Bug
Components: core
Environment: Hibernate 3.1. I believe this hasn't changed in CVS.
Reporter: Tzvetan Mikov
Assignee: Steve Ebersole
Priority: Minor
Fix For: 3.1.1
org.hibernate.util.SimpleMRUCache uses org.apache.commons.collections.ReferenceMap to map
HQLQueryPlanKey to HQLQueryPlan. However both the value and the key are stored with soft
references. The last 128 HQLQueryPlan-s are kept in a strong reference array, but the
cache keys aren't, so often cache entries cannot be found, even though the values
still exist in memory.
There is a comment in the source saying:
// both keys and values may be soft since value keeps a hard ref to the key (and there is
a hard ref to MRU values)
but it isn't actually true since the value (HQLQueryPlan) doesn't actually keep a
reference to the key (HQLQueryPlanKey).
This is a simplistic patch that should fix the problem:
--- SimpleMRUCache.java 2005-12-12 07:03:46.000000000 -0800
+++ SimpleMRUCache-new.java 2005-12-28 18:34:09.920112661 -0800
@@ -16,20 +16,24 @@
private static final int MAX_STRONG_REF_COUNT = 128; //TODO: configurable?
private final transient Object[] strongRefs = new Object[MAX_STRONG_REF_COUNT];
//strong reference to MRU queries
+ private final transient Object[] strongKeyRefs = new Object[MAX_STRONG_REF_COUNT];
private transient int strongRefIndex = 0;
private final transient Map softQueryCache = new ReferenceMap(ReferenceMap.SOFT,
ReferenceMap.SOFT) ;
- // both keys and values may be soft since value keeps a hard ref to the key (and there
is a hard ref to MRU values)
public synchronized Object get(Object key) {
Object result = softQueryCache.get( key );
if( result != null ) {
- strongRefs[ ++strongRefIndex % MAX_STRONG_REF_COUNT ] = result;
+ ++strongRefIndex;
+ strongRefs[ strongRefIndex % MAX_STRONG_REF_COUNT ] = result;
+ strongKeyRefs[ strongRefIndex % MAX_STRONG_REF_COUNT ] = key;
}
return result;
}
public void put(Object key, Object value) {
softQueryCache.put( key, value );
- strongRefs[ ++strongRefIndex % MAX_STRONG_REF_COUNT ] = value;
+ ++strongRefIndex;
+ strongRefs[ strongRefIndex % MAX_STRONG_REF_COUNT ] = value;
+ strongKeyRefs[ strongRefIndex % MAX_STRONG_REF_COUNT ] = key;
}
}
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: