Hibernate Books

All times are UTC - 5 hours [ DST ]



Post new topic Reply to topic  [ 49 posts ]  Go to page 1, 2, 3, 4  Next
Author Message
 Post subject: memory leak because of many-to-one lazy loading
PostPosted: Wed Sep 21, 2005 12:27 pm 
Beginner
Beginner

Joined: Tue Jan 04, 2005 5:39 am
Posts: 37
Hibernate version: 3.0.5

Hi everybody!

Consider the following model:

Code:
class A {
    B b; // B is mapped with many-to-one association.

    public void getB() {
    }
}

class B {
    ...

    public void foo() {
    }

    ...
}


After loading object A with Session.load method, I'm calling B's foo() method:

Code:
a.getB().foo()


After doing that, object B (and A) are never released - even after transaction is ended. I think this is a wrong behavior which causes a memory leak.

I think that the reason is:

This scenario causes CGLIBLazyInitializer to load object B and to store it in its "target" data member. As I understand, CGLIBLazyInitializer is registered as some kind of "callback" in the CGLib framework. CGLib framework stores an array of those "callbacks" in the ThreadLocal variable.

The trouble is: I'm working with Tomcat. I'm opening (an closing) transaction for every request to the Web Server. But Tomcat reuses its threads, so ThreadLocals live beyond the transactional scope and those object B will live after the transaction is ended.

Am I doing something wrong? Or is it a bug?? I have rechecked it several times with a profiler.

Thanks a lot!
Michael.


Top
 Profile  
 
 Post subject:
PostPosted: Sun Sep 25, 2005 2:14 am 
Beginner
Beginner

Joined: Tue Jan 04, 2005 5:39 am
Posts: 37
Guys?? Hibernate team? Gavin? :)


Top
 Profile  
 
 Post subject:
PostPosted: Sun Sep 25, 2005 2:19 am 
Expert
Expert

Joined: Mon Jul 04, 2005 5:19 pm
Posts: 720
stacktrace?


Top
 Profile  
 
 Post subject:
PostPosted: Sun Sep 25, 2005 3:18 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 6:10 am
Posts: 8611
Location: Neuchatel, Switzerland (Danish)
you do remember to close your session, correct ?

_________________
Max
Don't forget to rate


Top
 Profile  
 
 Post subject:
PostPosted: Sun Sep 25, 2005 7:03 am 
Beginner
Beginner

Joined: Tue Jan 04, 2005 5:39 am
Posts: 37
Max: of course

dennisbyrne: what stack trace? It's a memory leak - Just to do the same and capture memory snapshot after transaction is ended ...


Top
 Profile  
 
 Post subject:
PostPosted: Sun Sep 25, 2005 9:24 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 6:10 am
Posts: 8611
Location: Neuchatel, Switzerland (Danish)
I don't know of any part of hibernate holding hard references to the instance besides the session, incl. cglib stuff.

_________________
Max
Don't forget to rate


Top
 Profile  
 
 Post subject:
PostPosted: Sun Sep 25, 2005 10:13 am 
Beginner
Beginner

Joined: Tue Jan 04, 2005 5:39 am
Posts: 37
Can you please run my scenario and capture the memory snapshot?

You will see that references are still there after transaction has ended.

I'm using YourKit profiler, if you have it, i can send you the snapshot where you'll see the problem.


Top
 Profile  
 
 Post subject:
PostPosted: Sun Sep 25, 2005 10:14 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 6:10 am
Posts: 8611
Location: Neuchatel, Switzerland (Danish)
are you sure it is just not the *classes* and not the instances it refers to ?

_________________
Max
Don't forget to rate


Top
 Profile  
 
 Post subject:
PostPosted: Sun Sep 25, 2005 10:34 am 
Beginner
Beginner

Joined: Tue Jan 04, 2005 5:39 am
Posts: 37
Absolutly.

I've rechecked it now. The snapshot size is 170MB, i can upload it to you if you wish.

Thanks!


Top
 Profile  
 
 Post subject:
PostPosted: Sun Sep 25, 2005 12:44 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 6:10 am
Posts: 8611
Location: Neuchatel, Switzerland (Danish)
Read this thread and take notes - im pretty sure it something similar to what you see.

http://forum.hibernate.org/viewtopic.ph ... t=redeploy

(and just so you read it correctly: Noone have shown that the recent Hibernate and related libraries have any memory leak...only that someone have shown classes are sometimes left hanging to "other gc roots" which is not a problem only for hibernate...)

_________________
Max
Don't forget to rate


Top
 Profile  
 
 Post subject:
PostPosted: Mon Sep 26, 2005 3:37 am 
CGLIB Developer
CGLIB Developer

Joined: Thu Aug 28, 2003 1:44 pm
Posts: 1217
Location: Vilnius, Lithuania
Send mail to cglib list if it can be reproduced.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Sep 26, 2005 4:33 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 6:10 am
Posts: 8611
Location: Neuchatel, Switzerland (Danish)
btw. i just tried to reproduce this stuff.

What I did was to run a selected part of hibernate unit test and selectively call sf.close() and session.close() and perform object dumps - and there were 0, Zero, no references to object domain instances from hibernate code after this.

The only object reference were inside junit which apparently has a hashmap with some instances for caching of result or something.

One thing i did note though were that we kept references to cglib generated classes (FastClass and BulkBean) even after sf.close().

They went away when I did a sf = null; session = null;, again it was not the actual instances but i'll examine why we don't empty those session factories completely.

/max

_________________
Max
Don't forget to rate


Top
 Profile  
 
 Post subject:
PostPosted: Mon Sep 26, 2005 5:46 am 
Beginner
Beginner

Joined: Tue Jan 04, 2005 5:39 am
Posts: 37
Hi Guys!

I've read a thread about a "realoading" issues. I'm 100% sure that this is something else - I never reload my application.

I've also checked SessionFactoryImpl's and SessionImpl's "close" methods, i didn't see any connection to this problem.

Can i please upload a snapshot (about 170MB), and you'll take a look?


Top
 Profile  
 
 Post subject:
PostPosted: Mon Sep 26, 2005 7:01 am 
Beginner
Beginner

Joined: Tue Jan 04, 2005 5:39 am
Posts: 37
I looked again at this problem. I'm almost 100% sure that it is a bug ...

As I sad earlier, CGLIBLazyInitializer is an implementation of a Callback interface. It's stored in the ThreadLocal after being passed to one of Factory's or Enhancer's methods. On the other hand, CGLIBLazyInitializer is holding hard references to SessionImpl and to the target domain object.

A I see it, the solution can be one of:

1. Hibernate should invoke some kind of cleanup method to cause CGLib to remove it's ThreadLocals after transaction has ended.

2. CGLIBLazyInitializer should hold weak/soft references to SessionImpl and target domain objects.

What do you think?

If you can, please take a closer look at this problem. Remember, it occurs only when methods on proxies generated by CGLIBLazyInitializer are invoked.

Thanks a lot!
Michael.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Sep 26, 2005 8:03 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 6:10 am
Posts: 8611
Location: Neuchatel, Switzerland (Danish)
and you are using the latest version of hibernate and its libraries ?

and since it has nothing to do with reload it should be easily reproducable with a small 10 line java code and mapping - please provide that instead of 170 meg memory dumps ,)

Again, i could not reproduce in our testsuite which uses the cglib stuff extensively.

-max

_________________
Max
Don't forget to rate


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 49 posts ]  Go to page 1, 2, 3, 4  Next

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.