-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 2 posts ] 
Author Message
 Post subject: Possible NHibernate SessionFactory (LRUMap) Memory Leak?
PostPosted: Thu Dec 11, 2008 10:08 am 
Newbie

Joined: Wed May 28, 2008 5:04 pm
Posts: 3
Hi,

[Disclaimer: Posted this on nhusers, but I realized that this is probably a more correct forum]

I have been trying to pin down a memory leak in my wep app these past few weeks - and digging into my application with WinDbg revealed something fishy with the NHibernate SessionFactory in memory.

Context: It's a standard ASP.NET application using NHibernate 2.0.0.4000. I only use 1 SessionFactory since that seems to be the defacto standard - and my Sessions are disposed using something along the lines of Ayende's unit of work.

I have been analyzing a memory dump of a ~800mb .NET heap to figure out why it kept growing. One thing I found was around 1.9 million NHibernate.SqlCommand.SqlStrings and ~90000 HQLQueryPlans

MT Count TotalSize Class Name
0f7fb3e4 92382 3695280 NHibernate.Engine.Query.HQLQueryPlan
0eafd714 1939496 31031936 NHibernate.SqlCommand.SqlString

Digging down into the roots of one of these SqlStrings revealed that it was being stored in the query plan cache in the SessionFactoryImpl:

067016bc(NHibernate.Impl.SessionFactoryImpl)->
06702470(NHibernate.Engine.Query.QueryPlanCache)->
06703050(NHibernate.Util.SoftLimitMRUCache)->
067030a0(NHibernate.Util.LRUMap)->
067030d4(System.Collections.Hashtable)->
0c8af170(System.Collections.Hashtable+bucket[])->
02e30ccc(NHibernate.Util.SequencedHashMap+Entry)->
02e2efdc(NHibernate.Engine.Query.HQLQueryPlan)->
02e2f1dc(System.Object[])->
02e2f1f0(NHibernate.Hql.Classic.QueryTranslator)->
02e2f4c4(System.Collections.Generic.List`1[[NHibernate.SqlCommand.SqlString, NHibernate]])

I checked and there was exactly 1 instance of the SessionFactoryImpl in the dump - checking it's size took a few hours, which is not surprising:

sizeof(067016bc) = 716798348 bytes (NHibernate.Impl.SessionFactoryImpl)

That is one big SessionFactory :-) Still tracking the SqlString I explored the query plan cache and ended up at the LRUMap, which according to the code is supposed to keep the last (128 in this case) most recently used queries in cache. The LRUMap looked like this:

Name: NHibernate.Util.LRUMap
Fields:
MT Field Offset Type VT Attr Value Name
0f76a554 4000e40 c ...ncedHashMap+Entry 0 instance 067030bc _sentinel
79101fe4 4000e41 10 ...ections.Hashtable 0 instance 067030d4 _entries
790ffcc8 4000e42 4 System.Int64 1 instance 104874 _modCount
79102290 4000e51 14 System.Int32 1 instance 128 maximumSize

That is, 128 max size. Examining the hashtable called Entries in the LRUMap revealed this though (some lines removed):

Name: System.Collections.Hashtable
Size: 56(0x38) bytes
Fields:
MT Field Offset Type VT Attr Value Name
7912d9bc 400092b 4 ...ashtable+bucket[] 0 instance 0c8af170 buckets
79102290 400092c 1c System.Int32 1 instance 92382 count
79102290 400092d 20 System.Int32 1 instance 35331 occupancy
79102290 400092e 24 System.Int32 1 instance 112634 loadsize
79102290 4000930 2c System.Int32 1 instance 92391 version

Supposedly it contains ~90000 objects (count field) and a big (reachable) object size:
sizeof(067030d4) = 716798264 bytes (System.Collections.Hashtable)

I have examined the LRUMap source and can't find any glaring mistakes, I looked at the LRUMapFixture, which didn't seem to contain any tests that verify that it actually is limited to it's max size. However, I made a unit test in my own test project:

[Test]
public void LRUTest()
{
LRUMap map = new LRUMap(10);

for (int i = 0; i < 20000; i++)
map.Add("str" + i, i);

Assert.AreEqual(10, map.Count);
}

and this passed just fine.

Now this is where I am stumped, somehow my application manages to squeeze all these objects into the cache, but I haven't been able to reproduce it with simple tests.

Does anyone have an idea what could be the culprit?


Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 12, 2008 4:29 am 
Newbie

Joined: Wed May 28, 2008 5:04 pm
Posts: 3
Was answered on nhusers:

http://groups.google.com/group/nhusers/browse_thread/thread/ad3090edcfb115ef


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 2 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.