
| Key: |
NUCCORE-552
|
| Type: |
Bug
|
| Status: |
Closed
|
| Resolution: |
Fixed
|
| Priority: |
Major
|
| Assignee: |
Unassigned
|
| Reporter: |
Yang ZHONG
|
| Votes: |
0
|
| Watchers: |
0
|
|
If you were logged in you would be able to see more operations.
|
|
|
|
org.datanucleus.FetchGroup#planListeners holds strong references of org.datanucleus.FetchPlan, unfortunately, FetchGroup#deregisterListener is normally never invoked in RunTime. Since FetchPlan holds strong reference of org.datanucleus.ObjectManagerImpl which holds strong reference of org.datanucleus.jdo.JDOPersistenceManager, FetchGroup#planListeners leaks memory quickly soon Out Of Memory.
The Test Case to be attached, shows both FetchPlan & PersistenceManager still referenced after GC.
Just for the only purpose of Proof of Concept, following refinements seem solved the problem:
3-1. Add this into JDOPersistenceManager#close()
fetchPlan.clearGroups();
3-2. Add this into org.datanucleus.jdo.JDOQuery#closeAll()
if (fetchPlan != null)
fetchPlan.clearGroups();
3-3. Add this into org.datanucleus.store.rdbms.query.legacy.JDOQLQuery
public void closeAll()
{
super.closeAll();
if (candidates instanceof CollectionCandidates)
{
((CollectionCandidates)candidates).getFetchPlan().clearGroups();
}
else if (candidates instanceof Extent)
{
((Extent)candidates).getFetchPlan().clearGroups();
}
}
Now the Test Case shows both FetchPlan & PersistenceManager GCed!
However, neither is user obligated to close()/clossAll(), nor should a JDO implementation count on so. Therefore, I personally think the real fix should be weakly referencing FetchGroup#planListeners elements, such as WeakHashMap#keySet().
After the real fix, both "pm.close();" & "query.closeAll();" should be commented out of the Test Case to verify the fix.
Given the weakly referencing fix, I personally still recommend above code change as they help GC.
|
|
Description
|
org.datanucleus.FetchGroup#planListeners holds strong references of org.datanucleus.FetchPlan, unfortunately, FetchGroup#deregisterListener is normally never invoked in RunTime. Since FetchPlan holds strong reference of org.datanucleus.ObjectManagerImpl which holds strong reference of org.datanucleus.jdo.JDOPersistenceManager, FetchGroup#planListeners leaks memory quickly soon Out Of Memory.
The Test Case to be attached, shows both FetchPlan & PersistenceManager still referenced after GC.
Just for the only purpose of Proof of Concept, following refinements seem solved the problem:
3-1. Add this into JDOPersistenceManager#close()
fetchPlan.clearGroups();
3-2. Add this into org.datanucleus.jdo.JDOQuery#closeAll()
if (fetchPlan != null)
fetchPlan.clearGroups();
3-3. Add this into org.datanucleus.store.rdbms.query.legacy.JDOQLQuery
public void closeAll()
{
super.closeAll();
if (candidates instanceof CollectionCandidates)
{
((CollectionCandidates)candidates).getFetchPlan().clearGroups();
}
else if (candidates instanceof Extent)
{
((Extent)candidates).getFetchPlan().clearGroups();
}
}
Now the Test Case shows both FetchPlan & PersistenceManager GCed!
However, neither is user obligated to close()/clossAll(), nor should a JDO implementation count on so. Therefore, I personally think the real fix should be weakly referencing FetchGroup#planListeners elements, such as WeakHashMap#keySet().
After the real fix, both "pm.close();" & "query.closeAll();" should be commented out of the Test Case to verify the fix.
Given the weakly referencing fix, I personally still recommend above code change as they help GC. |
Show » |
Sort Order:
|