Hi Morris,
we patched Xalan using the patch described in #6075
(we've just commented out m_freeStack.addElement(obj); ).
I imagine, that's a link from the iteratorpool to the
TransformerImpl causing trouble. Transforming sequentially, these
iteratorpool-references are reused and
thoug TransformerImpl Objects are kept referenced, they don't become more
(because the older ones are able to be freed by GC). But concurrent
transformation cause an increasment of "hanging" TransformerImpl Objects. Using
a profiler you can see it.
After patching no TransformerImpl was referenced after the transformation since
the TransformerImpl Object has only the scope of the method.
Unfortunately patching changes somehow the memory usage. Big stylesheets caused
a memory consumtion of several MBs more. (Maybe we don't saw the truth, because
the JVM takes almost all memory it has before running GC and our profiler shows
only "JVM used" memory.
"Cloning the Template" is just a Hack to keep memory consumption lower and to
prevent TransformerImpls from hanging around.
Stefan
-----Ursprüngliche Nachricht-----
Von: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]
Gesendet: Do 28.11.2002 03:55
An: Stefan Kaesberg
Cc: [EMAIL PROTECTED]
Betreff: Re: AW: Tomcat out-of-memory-error when caching XSLT
Hi, Stefan
I have a question for you. In the following statement, do you mean the
patch in your note or the patch originally suggested in bug 6075 (i.e.
comment out the line in IteratorPool.freeInstance)?
>> The patch stops the memory leaking problem, but after patching the
>> transformation needs 30MB more memory.
Morris Kwan
XSLT Development
IBM Toronto Lab
Tel: (905)413-3729
Email: [EMAIL PROTECTED]
<Stefan.Kaesberg@
avinci.de> To: <[EMAIL
PROTECTED]>, <[EMAIL PROTECTED]>
cc:
11/28/2002 04:20 Subject: AW: Tomcat
out-of-memory-error when caching XSLT
AM
Hi,
for org.apache.xalan.processor.TransformerFactoryImpl i think xalan bug
#6075 causes the problem.
We've got the same problem using it in concurrent requests. Using a
memory
profiler we saw that
the TransformerImpl Objects are still referenced after usage.
Transforming
parallely lets "spawn" the TransformerImpl Objects (~1,5 MB each with
it's
stuff). The patch stops the memory leaking problem, but after patching
the
transformation needs 30MB more memory (because optimization is turned
off
?).
Since you only have 256 MB it'll be not the best solution. Maybe you
synchronize the transformation (your stylesheet is smaller than ours).
To
prevent starvation you should implement something like a
priority-mechanism. Of course you should cache the templates because
parsing the stylesheet is a timeconsuming process. I've tried out to
"clone" the Templates-Object by serializing and deserializing. Because
there's a reference from the Templates Object to the TransformerImpl
Object
and we cache the Templates Object, the GC can't delete the
TransformerImpl
Object and it's stuff (~1,5 MB). When i "cloned" the Template with:
// Memory-leaking (Xalan 2 Bug #6075)
// Patch begins:
// javax.xml.transform.Transformer transformer =
getTemplate(url).newTransformer();
// CLONE Template (Hack until xalan-bug #6075 resolved:
org.apache.xalan.templates.StylesheetRoot template =
(org.apache.xalan.templates.StylesheetRoot)getTemplate(url);
javax.xml.transform.Transformer transformer = null;
// Serialize Object:
try
{
long startTime = System.currentTimeMillis();
ByteArrayOutputStream os = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(os);
oos.writeObject(template);
// Deserialize Object:
ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray());
ObjectInputStream ois = new ObjectInputStream(is);
// Replace Templates-Object by serialized one:
template = (org.apache.xalan.templates.StylesheetRoot)ois.readObject();
long endTime = System.currentTimeMillis();
transformer = template.newTransformer();
}
catch(Exception e)
{
e.printStackTrace();
}
// Finally transform:
// End of Patch
transformer.transform(source, result);
it worked fine because the "cloned" Template is not referenced after the
method and GC frees all.
Cloning took ~100 ms, but some of our templates reference classes which
don't support serialization :-(
Maybe it helps. Stefan