[hibernate-issues] [Hibernate-JIRA] Commented: (HHH-2481) Big memory leak in the use of CGLIB

Paul Malolepsy (JIRA) noreply at atlassian.com
Tue Mar 13 14:17:08 EDT 2007


    [ http://opensource.atlassian.com/projects/hibernate/browse/HHH-2481?page=comments#action_26451 ] 

Paul Malolepsy commented on HHH-2481:
-------------------------------------

The test case demonstraits that during the course of normal operation, a fully hydrated object managed by hibernate is stuck in static memory.  Creating any proxy object on any given thread will cause this behavior.   How much memory this leaks, and weather or not you get an OOM is dependent on:

1) How many proxy types your application has.
2) How many threads you create proxies on.
3) Most importantly, how large the object graph is that is attached to these proxy objects.

To create a test case that shows the OOM is very easy, but coming up with a test case that actually asserts if there is an imminent OOM is next to impossible in Java.  But the OOM is just a symptom of the real issue which is hydrated objects stuck in memory.  This alone should be a giant red flag.


As far as future instantiations, there should be no worry here.  Any time a proxy is ever instantiated, it is always preceded by the Enhancer.registerCallbacks() method.  In fact, the callback object is directly tied to the instance of the proxy being created so if this callback object was ever used by future instantiations, that would be a very bad thing.

> Big memory leak in the use of CGLIB
> -----------------------------------
>
>          Key: HHH-2481
>          URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-2481
>      Project: Hibernate3
>         Type: Bug

>   Components: core
>     Versions: 3.2.2
>  Environment: Hibernate 3.2.2
> MySQL 5.1
>     Reporter: Paul Malolepsy
>     Assignee: Scott Marlow
>     Priority: Critical
>  Attachments: fix.diff
>
> Original Estimate: 5 minutes
>         Remaining: 5 minutes
>
> The way CGLIBLazyInitializer is creating proxies is resulting in a potentially massive memory leak.
> In CGLIBLazyInitializer.getProxy() just before the proxy is instantiated, a call is made to Enhancer.registerCallbacks() passing in the instance of CGLIBLazyInitializer that will manage the proxy.  This variable is stored in a static ThreadLocal on the CGLIB created persistentClass so that any subsequent objects instantiated will get this callback class.  
> The problem is that once this ThreadLocal is set, it is never cleared, so it will stay around (together with the object it's managing, and whatever object graph it may be connected to) until the next time a proxy is created for that type on that thread.  
> For our application we have about 150 different proxy types, and our app can have over 100 threads.  This results in potentially 15,000 proxy objects and their graphs stuck in memory.
> The fix for this is simple.  Just make another call the Enhancer.registerCallbacks() with a null callback arg, right after the proxy class is instantiated:
> Enhancer.registerCallbacks(factory, null);

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
   http://opensource.atlassian.com/projects/hibernate/secure/Administrators.jspa
-
For more information on JIRA, see:
   http://www.atlassian.com/software/jira




More information about the hibernate-issues mailing list