On 31/01/2012 22:45, Gerry Kaplan wrote:

I am building an application that relies heavily on XSL transformations. In order to avoid repetitive XSL loading/compiling and document fetching (within the XSL), I have created a class that encapsulates the Transformer object, creating it at instantiation and holding it until the application shuts down. Although the XSL itself is not particularly big, it fetches a large XML document (using document() function) which takes time. Therefore, caching is essential.

 


Don't reuse the Transformer unless you want to reuse the resources it has acquired. Cache the Templates object (the compiled stylesheet), and create a new Transformer for each transformation.

You can reuse the Transformer (serially, in the same thread) if you really want to, and it can be useful to do so if there are static documents such as lookup data used in every transformation. But if you don't want to hold on to the documents used by one transformation in subsequent transformations, then either (a) create a new Transformer (recommended), or (b) call its reset() and clearDocumentPool() methods before reusing it.

Creating a new Transformer for each transformation does not prevent you retaining source documents in memory and using them repeatedly: write a URIResolver that manages the document pool, deciding which documents to keep and which to discard. For this kind of thing it's much easier to use s9api interfaces rather than JAXP (which doesn't recognize any kind of in-memory document other than a DOM).

Unfortunately the JAXP documentation gives very poor advice as far as Saxon is concerned: it advises reusing a Transformer in order to reuse resources, but reusing resources means retaining resources, and retaining resources that don't need to be retained is what many Java users characterize as a "memory leak".

Michael Kay
Saxonica