Potentially serious memory leak with regards to NHibernate.Action.EntityAction.BeforeTransactionCompletionProcessDelegate

Description

When I save some entities with Session.Save, I noticed all object states still live in the memory even if I flush and clear the session.

I used windbg and I saw ,the object states live in NHibernate.Action.EntityInsertAction.states field. However I couldn't understand why the object states still kept despite I cleared the session. Then from windbg I saw the following relation by running !gcroot

00000000029085f0(NHibernate.Impl.SessionImpl)->
00000000029086f8(NHibernate.Engine.ActionQueue)->
0000000002908b00(NHibernate.Engine.ActionQueue+BeforeTransactionCompletionProcessQueue)->
0000000002908b20(System.Collections.Generic.List`1[[NHibernate.Action.BeforeTransactionCompletionProcessDelegate, NHibernate]])->
000000000290c5d0(System.Object[])->
000000000290c590(NHibernate.Action.BeforeTransactionCompletionProcessDelegate)->
000000000290c060(NHibernate.Action.EntityInsertAction)

It is seen the EntityInsertAction is being hold by BeforeTransactionCompletionProcessDelegate.

I check the NHibernate.Action.EntityAction type and saw

Basically nhibernate keeps these delegates for interceptors and because of this, the EntityAction object lives in the memory ("this" pointer in above code).
However it is not so common that we have any listener for BeforeTransactionCompletion. So we are keeping the object state's for no reason. Look at same code for

As you see it checks if there is any requirements . If not then returns null. Same should be done for BeforeTransactionCompletionProcessDelegate
. I can't believe how this bug is lived so far. It is causing a lot of memory used for nothing.

Environment

None

Activity

Show:

Alex Zaytsev May 1, 2017 at 3:42 AM

Closing issues resolved in 4.1.0

Carlos Montagut February 23, 2016 at 3:44 PM

Alex Zaytsev February 16, 2016 at 9:39 PM

the pull request will be highly appreciated

Carlos Montagut February 16, 2016 at 3:59 PM

We detected a similar issue in NHibernate.Action.CollectionAction and CollectionUpdateAction.

A list of AfterTransactionCompletionProcessDelegate is keept which have a reference to the related entities. These deletegates don't have any effect if the 2nd level cache is not activated, only consuming memory...

At the end of the transaction, doesn't matter if we called Session.Clean(), the entities are still referenced, consuming lot of memory.

We have documented this with a MemoryProfiler, and also we can build a kind of test, we spot this issue when Saving entities with OneToMany relations with cascade all. Also we can create a pull request with the suggested solution.

Oskar Berggren November 22, 2014 at 3:23 PM

Nominating for 4.1.

Fixed

Details

Assignee

Reporter

Labels

Components

Fix versions

Affects versions

Priority

Who's Looking?

Open Who's Looking?
Created February 3, 2012 at 11:27 AM
Updated July 20, 2018 at 9:23 AM
Resolved February 26, 2016 at 11:18 AM
Who's Looking?