[
http://opensource.atlassian.com/projects/hibernate/browse/HHH-2470?page=c...
]
Harry Mark updated HHH-2470:
----------------------------
Attachment: hibernate-patch.zip
I experienced a big memory leak in production because of this bug, and so I have fixed
it.
The problem is not the NativeSQLQuerySpecification, but with the implementations of the
NativeSQLQueryReturn interface which it uses.
The two implementations, NativeSQLQueryScalarReturn & NativeSQLQueryNonScalarReturn,
do not implement equals() or hashCode(). However, these methods are used implicitly in
the equals() & hashCode() for NativeSQLQuerySpecification.
Because these were not implemented, the hashCode() for every instance of
NativeSQLQuerySpecification was different, causing the QueryPlanCache to not find the
existing entry in the planCache, so it would continually add objects to the cache. Also,
equals() needed to be implemented so that hash table lookup will work.
Attached is a patch for this bug. Copy the hibernate jar to be patched to the
patch\hibernate3 folder, then run "ant" from that folder. It will compile and
patch those 2 classes in the jar.
Harry
Use of session.createSQLQuery causes memory leak
-------------------------------------------------
Key: HHH-2470
URL:
http://opensource.atlassian.com/projects/hibernate/browse/HHH-2470
Project: Hibernate3
Issue Type: Bug
Components: query-sql
Affects Versions: 3.1.3
Environment: Win XP, Oracle 10g, Java 1.4.2
Reporter: Bjørn Bjerkeli
Attachments: hibernate-patch.zip, TestCase.zip
NativeSQLQuerySpecification fails to properly implement equals and hashcode caused by
lacking implementation of hashCode and equals in all SQLQueryReturn implementations and
SQLQueryScalarReturn which are members of NativeSQLQuerySpecification. I can see that
NativeSQLQuerySpecification has been changed in 3.2, but the problem is still there.
NativeSQLQuerySpecification instances are used as keys for retrieving and caching
NativeSQLQueryPlan instances.
This causes the caching-mechanism to be pretty useless when Queries created by
session.createSQLQuery because new entries will be added all the time in the
QueryPlanCache and the SoftLimitMRUCache member.
So far so good, the more serious problem that is caused by this is stems from the
implementation of SoftLimitMRUCache which again uses LRUMap in commons-collection. The put
- method of the cache is not treadsafe, and that causes the following fragment in LRUMap
to allow the map to grow beyond its maximumSize. That is bacause the containsKey method
will return an incorrect result when concurrently updating the map.
public Object put( Object key, Object value ) {
int mapSize = size();
Object retval = null;
if ( mapSize >= maximumSize ) {
// don't retire LRU if you are just
// updating an existing key
if (!containsKey(key)) {
// lets retire the least recently used item in the cache
removeLRU();
}
}
retval = super.put(key,value);
return retval;
}
I have included a test-case that demonstrates:
1) Wrong implementation of equals and hashCode in NativeSQLQuerySpecification
2) Concurrent use of LRUMap causes the map to grow beyound it's max limit
3) Concurrent execution of session.createSQLQuery causes memory leak due to 1) and 2)
I would be more than happy to contribute to get this fixed. Just let me know.
--
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