I've also written a really simple web example to show a data entity hanging
around in memory after the request is finished with:
If I call "Get<User>(userId)" - the User object is still in memory once the
request has ended (GC has been run)......aaany ideas?
*Code sample:*
protected void Page_Load(object sender, EventArgs e)
{
int userId = CreateUser(SessionSource.Instance.SessionFactory);
GetUser(SessionSource.Instance.SessionFactory, userId);
}
private static void GetUser(ISessionFactory sessionFactory, int
userId)
{
ISession session = sessionFactory.GetCurrentSession();
User user = session.Get<User>(userId);
}
private static int CreateUser(ISessionFactory sessionFactory)
{
User user = new User();
user.Created = DateTime.Now;
user.Email = "[email protected]";
user.Enabled = true;
user.FirstName = "first name";
user.LastName = "last name";
user.Password = "password";
user.ScreenName = "firstname lastname";
ISession session = sessionFactory.GetCurrentSession();
session.SaveOrUpdate(user);
return user.Id;
}
*HttpModule*:
private static void BeginRequest(object sender, EventArgs e)
{
ISession session =
SessionSource.Instance.SessionFactory.OpenSession();
ManagedWebSessionContext.Bind(HttpContext.Current, session);
}
private static void EndRequest(object sender, EventArgs e)
{
ISession session =
ManagedWebSessionContext.Unbind(HttpContext.Current,
SessionSource.Instance.SessionFactory);
if (session == null) return;
session.Close();
session.Dispose();
}
*Session factory:*
SessionFactory = Fluently.Configure()
.Database(MsSqlConfiguration.MsSql2008.ConnectionString(DataConfig.ConnectionString))
.Mappings(x => GetFluantMappings(x)
.Conventions.Add(typeof
(EnumConvention)))
.ExposeConfiguration(c =>
{
c.SetProperty("generate_statistics", "true");
c.SetProperty("current_session_context_class", "managed_web");
c.SetProperty("cache.use_second_level_cache", "false");
c.SetProperty("cache.use_query_cache", "false");
})
.BuildSessionFactory();
*
*
*Paul Allington [image: See my
profile]<http://www.intelligentpenguin.co.uk/about/theteam/paul>
*
*T:* 01799 522 665
*M:* 07973 145 754
*E:* [email protected]
*W:* www.intelligentpenguin.co.uk
*W:* www.creative-penguin.co.uk
[image: Intelligent Penguin] <http://www.intelligentpenguin.co.uk> For
highly creative & technically brilliant websites, and on-line management
systems
------------------------------------------------------------------------------
My
profiles: [image: Facebook] <http://www.facebook.com/paulallington>[image:
LinkedIn] <http://uk.linkedin.com/in/paulallington>[image:
Twitter]<http://twitter.com/paulallington>
Contact me: [image: Google Talk/]phallington [image:
Skype/]paul-allington [image:
Y! messenger/]paul_allington
On Thu, Feb 10, 2011 at 10:50 AM, Paul Allington <
[email protected]> wrote:
> I've just written a reeeally simple console app to try and find where this
> unmanaged memory is coming from...8.7MB to 22MB is quite a jump - what's
> using it? Is that really runtime?
>
> Results:
>
> *Start of the App*
> Task Manager: 5,976 K
> Gen 1 Objects: 39.77 KB
> Gen 2 Objects: 0
> Large Object Heap: 35.58 KB
> Unused allocated memory: 28.25 KB
> Unmanaged 8.766 MB
>
> *After factory is created*
> Task Manager: 29,852 K
> Gen 1 Objects: 512.2 KB
> Gen 2 Objects: 799.3 KB
> Large Object Heap: 47.61 KB
> Unused allocated memory: 8.91 MB
> Unmanaged 21.95 MB
>
> *Paul Allington [image: See my
> profile]<http://www.intelligentpenguin.co.uk/about/theteam/paul>
> *
> *T:* 01799 522 665
> *M:* 07973 145 754
> *E:* [email protected]
> *W:* www.intelligentpenguin.co.uk
> *W:* www.creative-penguin.co.uk
> [image: Intelligent Penguin] <http://www.intelligentpenguin.co.uk> For
> highly creative & technically brilliant websites, and on-line management
> systems
>
> ------------------------------------------------------------------------------
> My
> profiles: [image: Facebook] <http://www.facebook.com/paulallington>[image:
> LinkedIn] <http://uk.linkedin.com/in/paulallington>[image:
> Twitter]<http://twitter.com/paulallington>
> Contact me: [image: Google Talk/]phallington [image: Skype/]paul-allington
> [image: Y! messenger/]paul_allington
>
>
>
>
> On Thu, Feb 10, 2011 at 9:21 AM, Paul Allington <
> [email protected]> wrote:
>
>> Thanks for that - very helpful.
>>
>> The snapshot is being taken after the request has completed. Am I the
>> only one who has a large chunk of unmanaged memory allocated when I use
>> nhibernate?
>>
>> *
>> *
>> *Paul Allington [image: See my
>> profile]<http://www.intelligentpenguin.co.uk/about/theteam/paul>
>> *
>> *T:* 01799 522 665
>> *M:* 07973 145 754
>> *E:* [email protected]
>> *W:* www.intelligentpenguin.co.uk
>> *W:* www.creative-penguin.co.uk
>> [image: Intelligent Penguin] <http://www.intelligentpenguin.co.uk> For
>> highly creative & technically brilliant websites, and on-line management
>> systems
>>
>> ------------------------------------------------------------------------------
>> My
>> profiles: [image: Facebook] <http://www.facebook.com/paulallington>[image:
>> LinkedIn] <http://uk.linkedin.com/in/paulallington>[image:
>> Twitter]<http://twitter.com/paulallington>
>> Contact me: [image: Google Talk/]phallington [image: Skype/]paul-allington
>> [image: Y! messenger/]paul_allington
>>
>>
>>
>>
>> On Wed, Feb 9, 2011 at 10:20 PM, John Davidson <[email protected]>wrote:
>>
>>> The code from Jason will work, but it assumes that the entire session
>>> happens in one transaction, which probably works in 99% of use cases, while
>>> the other 1% needs a different management strategy. This can be done by
>>> ensuring that a commit happens at the end of your first logical work unit
>>> and that it starts a new transaction for the second work unit.
>>>
>>> The other piece to check is that the http module is actually being used.
>>> It is bound into the aspx pipeline by the web.config file. The Register
>>> RequestHTTPModule section is important.
>>>
>>> Finally there is the question of when and how the memory snapshot is
>>> being generated. The snapshot needs to be taken when there is no active
>>> requests, i.e. when a web page has just completed loading, rather than while
>>> it is loading.
>>>
>>>
>>> On Wed, Feb 9, 2011 at 4:33 PM, Paul Allington <
>>> [email protected]> wrote:
>>>
>>>> Thanks - that's useful, I'll clean up the request code. Perhaps it's
>>>> just the way it managed the objects, but it doesn't explain the 30MB of
>>>> unmanaged memory - this I can't profile. Any clue what this could be?
>>>>
>>>> *
>>>> *
>>>> *Paul Allington [image: See my
>>>> profile]<http://www.intelligentpenguin.co.uk/about/theteam/paul>
>>>> *
>>>> *T:* 01799 522 665
>>>> *M:* 07973 145 754
>>>> *E:* [email protected]
>>>> *W:* www.intelligentpenguin.co.uk
>>>> *W:* www.creative-penguin.co.uk
>>>> [image: Intelligent Penguin] <http://www.intelligentpenguin.co.uk> For
>>>> highly creative & technically brilliant websites, and on-line management
>>>> systems
>>>>
>>>> ------------------------------------------------------------------------------
>>>> My
>>>> profiles: [image: Facebook] <http://www.facebook.com/paulallington>[image:
>>>> LinkedIn] <http://uk.linkedin.com/in/paulallington>[image:
>>>> Twitter]<http://twitter.com/paulallington>
>>>> Contact me: [image: Google Talk/]phallington [image: Skype/]paul-allington
>>>> [image: Y! messenger/]paul_allington
>>>>
>>>>
>>>>
>>>>
>>>> On Wed, Feb 9, 2011 at 9:05 PM, Jason Meckley
>>>> <[email protected]>wrote:
>>>>
>>>>> I think the problem is your transaction management in end request.
>>>>> rollback if error (good) else flush session (bad). call
>>>>> transaction.commit()
>>>>> instead and dispose of the transaction.
>>>>>
>>>>> some things to consider:
>>>>> 1. sessions are cheap so just create one for each request and dispose
>>>>> when the request ends.
>>>>> 2. all NH actions should be wrapped in a transaction if every request
>>>>> will require db access begin/end the transaction with the session. if not
>>>>> all WCF calls require NH, than manage the transaction with a decorator
>>>>> around the WCF call (similar to Filters in MVC frameworks)
>>>>>
>>>>> I would start by cleaning up the module code
>>>>>
>>>>> //begin request
>>>>> var session = SessionFactory.OpenSession();
>>>>> session.BeginTransaction();
>>>>> ManagedWebSessionContext.Bind(HttpContext.Current, session);
>>>>>
>>>>> //end request
>>>>> var session = ManagedWebSessionContext.Unbind(HttpContext.Current,
>>>>> SessionFactory);
>>>>> using(session)
>>>>> {
>>>>> using(var tx = session.Transaction)
>>>>> {
>>>>> if(Server.LastException == null)
>>>>> {
>>>>> tx.Commit();
>>>>> }
>>>>> else
>>>>> {
>>>>> tx.Rollback();
>>>>> }
>>>>> }
>>>>> }
>>>>>
>>>>> that's it. now if you want to manage the transaction per WCF action
>>>>> then the module would only manage the session
>>>>> //begin request
>>>>>
>>>>> ManagedWebSessionContext.Bind(HttpContext.Current,
>>>>> SessionFactory.OpenSession());
>>>>>
>>>>> //end request
>>>>> ManagedWebSessionContext.Unbind(HttpContext.Current,
>>>>> SessionFactory).Dispose();
>>>>>
>>>>> and a WCF decorator would manage the transaction. something like
>>>>> //decorator... wcfservice is the original/base implementation
>>>>> using(var txt = SessionFactory.GetCurrentSession().BeginTransaction())
>>>>> {
>>>>> try
>>>>> {
>>>>> wcfservice.Proceed();
>>>>> tx.Commit();
>>>>> }
>>>>> catch
>>>>> {
>>>>> tx.Rollback();
>>>>> throw;
>>>>> }
>>>>> }
>>>>>
>>>>> --
>>>>> You received this message because you are subscribed to the Google
>>>>> Groups "nhusers" group.
>>>>> To post to this group, send email to [email protected].
>>>>> To unsubscribe from this group, send email to
>>>>> [email protected].
>>>>> For more options, visit this group at
>>>>> http://groups.google.com/group/nhusers?hl=en.
>>>>>
>>>>
>>>> --
>>>> You received this message because you are subscribed to the Google
>>>> Groups "nhusers" group.
>>>> To post to this group, send email to [email protected].
>>>> To unsubscribe from this group, send email to
>>>> [email protected].
>>>> For more options, visit this group at
>>>> http://groups.google.com/group/nhusers?hl=en.
>>>>
>>>
>>> --
>>> You received this message because you are subscribed to the Google Groups
>>> "nhusers" group.
>>> To post to this group, send email to [email protected].
>>> To unsubscribe from this group, send email to
>>> [email protected].
>>> For more options, visit this group at
>>> http://groups.google.com/group/nhusers?hl=en.
>>>
>>
>>
>
--
You received this message because you are subscribed to the Google Groups
"nhusers" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/nhusers?hl=en.