Hi,

So, I've had hellish troubles the past couple of days with memory leaks in Glassfish/OSGI/Felix. Basically, when I uninstall my Qi4j app not everything was let go of, and the consequence is that the classloaders stay in memory, eventually causing a nice OutOfMemory error.

I've found some really bizarre things through debugging this, such as the MacOSX Preferences API implementation having a Timer thread referencing the ContextClassLoader that was set when the timer happened to be started (lazy start->random). This caused the OSGi classloader to be non-GC'able, and the only way I could get around it was to force this timer to be started while knowing that there was no context classloader for the thread. This is just one example, and they are in the same category.

So, having chased these issues one at a time, using VisualVM, heap dumps, and "Find GC Root", I'm now down to basically no objects being reachable from any GC root, and yet they're not GC'ed. Very annoying.

This has forced me to start looking into ditching CGLIB entirely. I'm now looking at ASM, since it can generate the classes we want. The main problem was figuring out how to use it. But it turns out there's a nice helper for it: basically write the Java code you want generated, and then the helper will create Java code to use ASM to create it.

So I've done that and am now trying to generify it so that it works for any class, apart from the test one I did. The general idea is this: if a mixin is marked as abstract we need to subclass it and implement all missing methods. When those methods are called the proxy shall be invoked. The basic template I'm using looks something like this:
public class SomeMixin_Stub
    extends SomeMixin
{
    private Object proxy;

    public SomeMixin_Stub( Object proxy )
    {
        super();

        this.proxy = proxy;
    }

    public String other()
    {
        return ((Other)proxy).other();
    }

    public String foo( String bar, int x )
    {
        return ((Other)proxy).foo( bar, x );
    }

    public void bar( double doub, boolean bool, float fl, char ch )
    {
        ((Other)proxy).bar( doub, bool, fl, ch );
    }
}
--
In the above I have a SomeMixin that implements an Other-interface with methods it's not actually implementing, so they have to be filled in. If I can generate the above, and do classloading that is OSGi-friendly, all should be fine. It might even be faster than what we do today. We'll see.

Any thoughts on this? Any gotchas in OSGi I should be aware of while doing this?

/Rickard

_______________________________________________
qi4j-dev mailing list
[email protected]
http://lists.ops4j.org/mailman/listinfo/qi4j-dev

Reply via email to