Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » EclipseLink » memory leaking
memory leaking [message #376894] Mon, 28 July 2008 14:35 Go to next message
Tom Eugelink is currently offline Tom EugelinkFriend
Messages: 817
Registered: July 2009
Senior Member
I'm using EclipseLink 1.0 in a stand alone Swing application which suffers from memory leaking.
I would really really appriciate it, if anyone can help me get on track again, because I'm completely stuck.
I know it is much to ask, but... Well... If I do not ask...

The application has two JFrames open, both for managing "Relations".
After working with the application for a while, the memory runs full: currently I have a memory dump of about 400 MB after only 3 hours of work.

If I examine the memory dump, I see the 2 screens (RelationObjectNavigator), 4 EntityManagers (correct), but out of the total of 880000 objects, 360000 are UnitOfWorkQueryValueHolder and 230000 are ReadObjectQuery or ReadAllQuery objects.
So just three classes are responsible for 67% of the classes.
Now, realistic memory usage would be something below 100 MB instead of almost 500.

If I inspect a few of the UnitOfWorkQueryValueHolder objects path-to-GC using Eclipse's MAT, I cannot explain why the objects still exist are are not GCed (I did do a GC before creating the memory dump).

For example the following path-to-GC:
1. org.eclipse.persistence.internal.indirection.UnitOfWorkQuery ValueHolder @ 0x1cba6398
2. valueHolder - org.eclipse.persistence.indirection.IndirectList @ 0x1cb42498
3. iRelationsWhereIAmRelation - nl.reinders.bm.Relation @ 0x1cb05730
4. [1] - java.lang.Object[16] @ 0x1cc81950
5. elementData - java.util.ArrayList @ 0x1cc78c40
6. val$returnSearchResult - org.tbee.swing.jpa.JpaEntitySearchBuilder$13 @ 0x1cc44ff8
7. [3] - java.lang.Object[4] @ 0x1cc2ce10
8. listenerList - javax.swing.event.EventListenerList @ 0x1cbf57f8
9. listenerList - javax.swing.JButton @ 0x1cbd37a8
10. val$lOkButton - org.tbee.swing.jpa.JpaEntitySearchBuilder$14 @ 0x1cb99c28
11. b - java.awt.AWTEventMulticaster @ 0x1cb37ca0

Analysis:
1&2&3: the Relation entity 0x1cb05730 has a lazy loading list of other Relation entities (forgive the property name).
4&5: the Relation object is entry [1] in the ArrayList
6: the ArrayList is held in the variable 'returnSearchResult' in JpaEntitySearchBuilder 0x1cc44ff8
7&8&9&10: the JpaEntitySearchBuilder is held at index [3] in the listenersList of the OkButton 0x1cb99c28.

I do not understand why this is not garbage collected. To show the code path, it starts in one of the JFrames; it has a filter Jbutton

// filter (this is an instance level button)
iFilter.addActionListener( new ActionListener(){ public void actionPerformed(ActionEvent e)
{
...
// builder (obtained from the cache or created)
JpaEntitySearchBuilder<T> lJpaEntitySearchBuilder = JpaEntitySearchBuilder.obtainJpaEntitySearchBuilder(getModel ().getEntityClass(), getSearchPrefix());

// search
List<T> lList = new ArrayList<T>(); // we can have only one return value, so the list is provided as a parameter
T lEntity = lJpaEntitySearchBuilder.searchSingleDialog( iSearch, Internationalization.get().translate(JpaObjectNavigatorBar.t his, "search"), lList );

// filter
// it is weird: even though we create our own list here, two bars within the same application overwrite each other.
// So we need to create yet another list here.
if (lList.size() > 0) getModel().doFilter( new ArrayList<T>(lList), lEntity );
else iFilter.setSelected(false);

// return
JpaEntitySearchBuilder.returnJpaEntitySearchBuilder(lJpaEnti tySearchBuilder);
}


With one minor step in between, this ends up in JpaEntitySearchBuilder:

protected List<T> searchDialog(Component component, String title, final int selectMode, final List<T> returnSearchResult)
{
...
final JButton lOkButton = new JButton( Internationalization.get().translate(this, "ok"), new ImageIcon(JpaObjectNavigatorBar.class.getResource("icon_ok.png ")) );
lOkButton.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e)
{
...
// returnSearchResult
if (returnSearchResult != null)
{
returnSearchResult.clear();
for (int lIdx = 0; lIdx < lJpaEntitySearchResultTableModelFinal.getRowCount(); lIdx++)
{
T lEntity = lJpaEntitySearchResultTableModelFinal.getEntity( lTableSorter.convertRowIndexToModel( lIdx ) );
returnSearchResult.add( lEntity );
}
}
...
}
}


This is it! A local list is instantiated in the action listener of the filter button, this is handed over to the JpaEntitySearchBuilder, which copies the data in the JpaEntitySearchResultTableModel into the list.
The when the action listener exits, the list should be GCed!

Now, my comment after the search method worries me. It appears there are conflicts between lists, even though they are separate lists.
Can it be the "final" on parameters in searchDialog has some unexpected side effects?
Re: memory leaking [message #376895 is a reply to message #376894] Mon, 28 July 2008 15:11 Go to previous messageGo to next message
Gordon Yorke is currently offline Gordon YorkeFriend
Messages: 78
Registered: July 2009
Member
You have 4 entity managers running. Are you clearing these entity
managers on a regular basis? You must clear the entity managers or use
the ReferenceMode property to have the VM manage the entity manager
contents for you.

Try setting "eclipselink.persistence-context.reference-mode" to "WEAK"
when creating an EntityManager.
--Gordon
Re: memory leaking [message #376897 is a reply to message #376895] Mon, 28 July 2008 19:40 Go to previous messageGo to next message
Tom Eugelink is currently offline Tom EugelinkFriend
Messages: 817
Registered: July 2009
Senior Member
I'm using programmatic configuration (I love compiler checks). Can you give me a pointer where to do this? I found the ReferenceMode enum.


Gordon Yorke wrote:
> You have 4 entity managers running. Are you clearing these entity
> managers on a regular basis? You must clear the entity managers or use
> the ReferenceMode property to have the VM manage the entity manager
> contents for you.
>
> Try setting "eclipselink.persistence-context.reference-mode" to "WEAK"
> when creating an EntityManager.
> --Gordon
>
Re: memory leaking [message #376898 is a reply to message #376895] Mon, 28 July 2008 19:44 Go to previous messageGo to next message
Tom Eugelink is currently offline Tom EugelinkFriend
Messages: 817
Registered: July 2009
Senior Member
Oh, I am clearing the two connected to the frames, but "failover" ones not, but they should not grow. But I cannot find to what EM an entity is attached in the GC path...
Re: memory leaking [message #376899 is a reply to message #376895] Tue, 29 July 2008 05:50 Go to previous messageGo to next message
Tom Eugelink is currently offline Tom EugelinkFriend
Messages: 817
Registered: July 2009
Senior Member
Hm. This is also very interesting; after a gc the memory dump is 16MB on disk, but the VM has 148MB memory allocated.
Re: memory leaking [message #377445 is a reply to message #376895] Wed, 30 July 2008 18:56 Go to previous messageGo to next message
Tom Eugelink is currently offline Tom EugelinkFriend
Messages: 817
Registered: July 2009
Senior Member
> Try setting "eclipselink.persistence-context.reference-mode" to "WEAK"
> when creating an EntityManager.

Please can anyone tell me how to set this value?

I've rewrote some memory handling, but I'm still experiencing a final local variable holding a reference. Why?
Re: memory leaking [message #377446 is a reply to message #376895] Wed, 30 July 2008 18:56 Go to previous messageGo to next message
Tom Eugelink is currently offline Tom EugelinkFriend
Messages: 817
Registered: July 2009
Senior Member
> Try setting "eclipselink.persistence-context.reference-mode" to "WEAK"
> when creating an EntityManager.

Please can anyone tell me how to set this value?

I've rewrote some memory handling, but I'm still experiencing a final local variable holding a reference. Why?
Re: memory leaking [message #377448 is a reply to message #377446] Thu, 31 July 2008 13:07 Go to previous messageGo to next message
James is currently offline JamesFriend
Messages: 272
Registered: July 2009
Senior Member
You can set this as a persistence.xml property, or a persistence unit
property.

But you should probably fix the memory leak in your application instead.
From your stack you were adding your JpaEntitySearchBuilder as an event
listener to the button, so as long as the button exists, so will your
event listener, and you event listener was holding onto the list of
Entityies which held everything else. You should clear the reference in
your event listener after it executes.

In general also clearing your EntityManager when your done with it would
be a good idea.

-- James
Re: memory leaking [message #377451 is a reply to message #377448] Thu, 31 July 2008 14:33 Go to previous messageGo to next message
Tom Eugelink is currently offline Tom EugelinkFriend
Messages: 817
Registered: July 2009
Senior Member
> You can set this as a persistence.xml property, or a persistence unit
> property.

Ah, ok.

> But you should probably fix the memory leak in your application
> instead. From your stack you were adding your JpaEntitySearchBuilder as
> an event listener to the button, so as long as the button exists, so
> will your event listener, and you event listener was holding onto the
> list of Entityies which held everything else. You should clear the
> reference in your event listener after it executes.

Not quite, it is an anonymous inner class inside the method that is added. Everything is method-local now, so there can't be a handing reference anymore.

It turns out there is a serious bug in the JDialog handling in Java 1.6. Never the less, that is not the cause of my problems.
It also turns out that windows task manager is a lousy way to check memory usage (try minimizing all windows of an application while the TM is open).


> In general also clearing your EntityManager when your done with it would
> be a good idea.

It is cleared, but this method is not responsible for that, but the caller does that.

Thanks!

Tom
Re: memory leaking [message #377452 is a reply to message #377448] Thu, 31 July 2008 14:40 Go to previous messageGo to next message
Tom Eugelink is currently offline Tom EugelinkFriend
Messages: 817
Registered: July 2009
Senior Member
> You can set this as a persistence.xml property, or a persistence unit
> property.

It sure is doing something but not what I hoped. :-)

[EL Warning]: 2008.07.31 16:37:39.890--UnitOfWork(20314099)--java.lang.NullPointerExc eption
at org.eclipse.persistence.internal.identitymaps.WeakUnitOfWork IdentityMap.cleanupDeadCacheKeys(WeakUnitOfWorkIdentityMap.j ava:31)
at org.eclipse.persistence.internal.identitymaps.WeakUnitOfWork IdentityMap.checkCleanup(WeakUnitOfWorkIdentityMap.java:62)
at org.eclipse.persistence.internal.identitymaps.WeakUnitOfWork IdentityMap.getCacheKeyIfAbsentPut(WeakUnitOfWorkIdentityMap .java:49)
at org.eclipse.persistence.internal.identitymaps.UnitOfWorkIden tityMap.acquireLock(UnitOfWorkIdentityMap.java:56)
at org.eclipse.persistence.internal.identitymaps.IdentityMapMan ager.acquireLock(IdentityMapManager.java:121)
at org.eclipse.persistence.internal.sessions.IdentityMapAccesso r.acquireLock(IdentityMapAccessor.java:76)
at org.eclipse.persistence.internal.sessions.IdentityMapAccesso r.acquireLock(IdentityMapAccessor.java:67)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.clo neAndRegisterObject(UnitOfWorkImpl.java:774)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.reg isterExistingObject(UnitOfWorkImpl.java:3571)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.reg isterExistingObject(UnitOfWorkImpl.java:3524)
at org.eclipse.persistence.queries.ObjectBuildingQuery.register IndividualResult(ObjectBuildingQuery.java:363)
at org.eclipse.persistence.internal.descriptors.ObjectBuilder.b uildWorkingCopyCloneNormally(ObjectBuilder.java:555)
at org.eclipse.persistence.internal.descriptors.ObjectBuilder.b uildObjectInUnitOfWork(ObjectBuilder.java:517)
at org.eclipse.persistence.internal.descriptors.ObjectBuilder.b uildObject(ObjectBuilder.java:461)
at org.eclipse.persistence.internal.descriptors.ObjectBuilder.b uildObject(ObjectBuilder.java:413)
at org.eclipse.persistence.queries.ObjectLevelReadQuery.buildOb ject(ObjectLevelReadQuery.java:521)
at org.eclipse.persistence.queries.ReadAllQuery.registerResultI nUnitOfWork(ReadAllQuery.java:893)
at org.eclipse.persistence.queries.ReadAllQuery.executeObjectLe velReadQuery(ReadAllQuery.java:486)
at org.eclipse.persistence.queries.ObjectLevelReadQuery.execute DatabaseQuery(ObjectLevelReadQuery.java:883)
at org.eclipse.persistence.queries.DatabaseQuery.execute(Databa seQuery.java:666)
at org.eclipse.persistence.queries.ObjectLevelReadQuery.execute (ObjectLevelReadQuery.java:844)
at org.eclipse.persistence.queries.ReadAllQuery.execute(ReadAll Query.java:456)
at org.eclipse.persistence.queries.ObjectLevelReadQuery.execute InUnitOfWork(ObjectLevelReadQuery.java:906)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.int ernalExecuteQuery(UnitOfWorkImpl.java:2588)
at org.eclipse.persistence.internal.sessions.AbstractSession.ex ecuteQuery(AbstractSession.java:1178)
at org.eclipse.persistence.internal.sessions.AbstractSession.ex ecuteQuery(AbstractSession.java:1162)
at org.eclipse.persistence.internal.sessions.AbstractSession.ex ecuteQuery(AbstractSession.java:1136)
at org.eclipse.persistence.internal.sessions.AbstractSession.ex ecuteQuery(AbstractSession.java:1118)
at org.eclipse.persistence.internal.jpa.EJBQueryImpl.executeRea dQuery(EJBQueryImpl.java:399)
at org.eclipse.persistence.internal.jpa.EJBQueryImpl.getResultL ist(EJBQueryImpl.java:517)
at nl.reinders.bm.generated.Btwcategory.findAllOrderedBy(Btwcat egory.java:260)
at nl.reinders.bm.Btwcategory.findAllOrderedByDescription(Btwca tegory.java:34)
at nl.reinders.gui.btwcategorie.BtwcategoryJComboBox.reloadList (BtwcategoryJComboBox.java:77)
at nl.reinders.gui.btwcategorie.BtwcategoryJComboBox.<init>(BtwcategoryJComboBox.java:38)
at nl.reinders.gui.btwcategorie.BtwcategoryJComboBox.<init>(BtwcategoryJComboBox.java:26)
at nl.reinders.gui.relation.RelationDetailPanel.construct(Relat ionDetailPanel.java:64)
at nl.reinders.gui.relation.RelationDetailPanel.<init>(RelationDetailPanel.java:52)
at nl.reinders.gui.relation.RelationObjectNavigator.constructRe lationDetail(RelationObjectNavigator.java:708)
at nl.reinders.gui.relation.RelationObjectNavigator.<init>(RelationObjectNavigator.java:95)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Nativ e Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Native ConstructorAccessorImpl.java:39)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(De legatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:5 13)
at java.lang.Class.newInstance0(Class.java:355)
at java.lang.Class.newInstance(Class.java:308)
at nl.reinders.Reinders$13.actionPerformed(Reinders.java:2290)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButto n.java:1995)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractB utton.java:2318)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultBu ttonModel.java:387)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel .java:242)
at javax.swing.AbstractButton.doClick(AbstractButton.java:357)
at javax.swing.AbstractButton.doClick(AbstractButton.java:337)
at nl.reinders.Reinders.startJpaScreenSwing(Reinders.java:2331)
at nl.reinders.Reinders.access$300(Reinders.java:127)
at nl.reinders.Reinders$12.run(Reinders.java:2220)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java :199)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:597)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDis patchThread.java:284)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispat chThread.java:184)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDis patchThread.java:174)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread. java:169)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread. java:161)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:12 2)
Re: memory leaking [message #378592 is a reply to message #377452] Tue, 05 August 2008 13:33 Go to previous messageGo to next message
James is currently offline JamesFriend
Messages: 272
Registered: July 2009
Senior Member
Could you please log a bug for this issue. It looks like this new
property has some issues.

https://bugs.eclipse.org/bugs/

-- James
Re: memory leaking [message #378614 is a reply to message #378592] Wed, 06 August 2008 13:59 Go to previous messageGo to next message
Gordon Yorke is currently offline Gordon YorkeFriend
Messages: 78
Registered: July 2009
Member
Bug created and patch attached :
http://bugs.eclipse.org/243300
--Gordon
Re: memory leaking [message #379027 is a reply to message #378614] Thu, 07 August 2008 07:11 Go to previous message
Tom Eugelink is currently offline Tom EugelinkFriend
Messages: 817
Registered: July 2009
Senior Member
When is the next semi-stable release due?
Previous Topic:how to
Next Topic:orm.xml vs Annotations
Goto Forum:
  


Current Time: Fri Mar 29 06:55:21 GMT 2024

Powered by FUDForum. Page generated in 0.05509 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top