Hi Steven,
Thanks for your speedy reply.
I understand that there is an object graph underneath the root object,
hense i understand it needs to load the 3828 descriptors for the object
graph underneath my root object. What i don't understand is why when
marshalling/unmarshalling the same root class (albeit with possibly
different values e.g., two objects of type person might have different
names but it's still the same name field) the resolver is loading more
descriptors but should in my opinion be using the same descriptors, it
is only the values that have changed not the class/fields. I understand
that in a complex object graph it may need to load more descriptors for
different objects due to it having a larger object graph - but my object
is staying relatively similiar each time - therefor i would expect some
growth but not constant growth with each iteration.
Also i'm not trying to create a resolver for every class - i'm creating
a resolver for each root class and reusing them (and yes i am setting
the resolver on the marshaller/unmashaller ;-). I don't think it is
thread safe either - so i've implemented it in a thread safe manner
I hope this sounds more like i'm implementing/understanding it all in
the right way.
I'm off to write a unit test now and do some further investigation :)
Thanks
Simon Lord
Steven Dolg wrote:
Hi Simon,
The 3828 FieldDescriptors indicate that the object graph your
(un)marshalling contains some more classes than the one you're creating
the ClassDescriptorResolver for.
So the (Un)marshaller asks the ClassDescriptorResolver to find all
descriptors necessary for the whole object graph (not just the root
object).
This might lead to creating different ClassDescriptorResolvers (for
different root classes) that might contain almost identical descriptors
(for all other objects in the object graph).
It shouldn't be necessary to create a ClassDescriptorResolver for each
class individually so I'd suggest using only one resolver. (I'm not
entirely sure whether this is thread-safe or not)
And do not forget to set the created ClassDescriptorResolver at the
(Un)marshaller... ;-)
Unmarshaller unm = new Unmarshaller(...);
unm.setResolver(cdr);
Regards,
Steven
----- Original Message ----- From: "Simon Lord" <[EMAIL PROTECTED]>
To: <[email protected]>
Sent: Wednesday, March 14, 2007 6:44 PM
Subject: [castor-user] [XML] XMLClassDescriptorResolver
XMLFieldDescriptorImpl cache possible memory leak
Afternoon all,
I've recently moved from using an old version of Castor (0.9.xxx) to
the new stable 1.1. Mainly as i'd like to use the descriptor caching.
However, after moving to castor 1.1 and creating an
XMLClassDescriptorResolver as per the xml-best-practices webpage,
running my application caused an out of memory expection (heapspace).
So i ran the code under jProfiler and have seen symptoms of a memory
leak (or symptoms of not using the resolver correctly ;-).
It my understanding that when marshalling/unmarshalling, the
XMLClassDescriptorResolver should be caching the descriptors for use
in subsequent operations. Then on the subsequent operation (marshal /
unmarshall) it shouldn't have to create those descriptors again
(assumming the same class/xml complex type is being used).
But what i've seen in jProfiler is that after one run of my code there
have been 3828 XMLFieldDescriptorImpl objects created (triggering
garbage collection a few times doesn't change that number either) then
when i run it again (no restart, just second iteration) it finishes
what it's doing and the count of XMLFieldDescriptorImpl objects is now
7725!
It increases with each iteration, and after 10 iterations is 38901
objects, taking up 3.4 megabytes in memory - after a while this gets
so big it causes the memory exception.
So it looks like it's created new XMLFieldDescriptorImpl for the same
classes and xml complex types i used the first time around.
Has anyone else seen this behaviour before? Am i doing somthing wrong
when creating / using the resolver?
Here's the code i use to contruct a resolver (sorry about the
formatting):
private XMLClassDescriptorResolver createResolver(Class clazz){
XMLClassDescriptorResolver cdResolver =
(XMLClassDescriptorResolver)ClassDescriptorResolverFactory.createClassDescriptorResolver(BindingType.XML);
cdResolver.setClassLoader(Thread.currentThread().getContextClassLoader());
try {
cdResolver.loadClassDescriptors(clazz.getPackage().toString());
return cdResolver;
} catch (ResolverException e) {
logger.warn(e.getMessage() + ":"+clazz.getPackage().toString(),e);
}
return null;
}
as you can see from the above code i create a resolver for each Class
i marshal/unmarshall and store it for subsequent uses of the same
operation (so i'm not creating a new resolver each time as it might
appear)
Thank you for your time
Simon Lord
---------------------------------------------------------------------
To unsubscribe from this list please visit:
http://xircles.codehaus.org/manage_email
---------------------------------------------------------------------
To unsubscribe from this list please visit:
http://xircles.codehaus.org/manage_email
---------------------------------------------------------------------
To unsubscribe from this list please visit:
http://xircles.codehaus.org/manage_email