User development,
A new message was posted in the thread "A few Javassist proxy patches":
http://community.jboss.org/message/529280#529280
Author : Mark Struberg
Profile :
http://community.jboss.org/people/struberg
Message:
--------------------------------------------------------------
Hi!
I'm working on Apache OpenWebbeans and we use javassist - so first of all thanks for
providing it!
I found a few issues which are mainly based on the way javassist got used in many
projects, which caused loss of permgenspace with every invocation. I tried to address this
with a few patches.
The problem is caused by the current javassist usage pattern of calling
ProxyFactory.createClass().newInstance() which currently (due to the broken cache), always
creates a new class for the proxy. And once this class gets classloaded, you cannot easily
get rid of it from the ClassLoaders class map. In the worst case the generated proxy class
gets registered in the SystemClassLoader and can never get freed again. Another problem is
that setting the default method handler with ProxyFactore.setMethodHandler() will store
this MethodHandler in a static field, thus the class will hold a reference to this
MethodHandler - even if it is not used anymore. Thus the MethodHandler (and all the
instances it references) imo can never get garbage collected.
There were also a few problems with deserialization, mainly because it did drop the
assigned MehodHandler and used the DefaultMethodHandler instead. I added new bytecode to
support MethodHandler serialization along with the proxyInstance.
To understand my need: instead of creating a fresh proxyClass every time, I switched OWB
to use the following pattern
1.) ProxyFactory.useCache = false; since the current implementation fo the internal class
cache imo inherently creates mem losses
2.) create the ProxyFactory only once and cache this class in our own code:
2.a) ProxyFactory pf = new ProxyFactory()
2.b) pf.setInterfaces(...);
2.c) pf.setSuperclass(...);
2.d) Class proxyClass = pf.creatClass();
3.) create a new proxy instance with it's own MethodHandler by always only using the
same cached proxy Class for a certain original class
Object proxyInstance = proxyClass.newInstance(); +
((ProxyObject)proxyInstance).setHandler(new BeanMethodHandler(beaninfo));
I didn't really need the MethodFilter in my use cases, so we need think about where
this fits into the picture.
Most foundings are explained in my patches available at github
http://github.com/struberg/javassist
Those patches are tested with OpenWebBeans and Weld (thanks to David R. Allen), but
I'm sure there is still room for improvement
One of the areas I'm not 100% sure is deserialization on another VM which may already
contain other proxy classes of that kind (with different javassist name). I now check if
the interfaces and the superclass is the same if I found a javassist proxyClass with
Class.forName on deserialization, maybe there is something missing still.
This szenario mainly may concern replication in big clusters, and the behaviour of the
patched version is of course heavily improved at least.
Oh yes, we should really cleanup the pom.xml!
I can volunteer with all the maven stuff too if needed.
txs and LieGrue,
strub
--------------------------------------------------------------
To reply to this message visit the message page:
http://community.jboss.org/message/529280#529280