Re: JDOM parser reuse memory problem

Rolf <[email protected]>
Newsgroups gmane.comp.java.jdom.general
Message-ID <[email protected]>
Hi again everyone.

I have been playing with SAXBuilder, trying to find a way to put it
together in such a way that it is still 'SAXBuilder' but improves parser
reuse, and still enables customization.

I think I have come up with a solution that is backward compatible
for 'everyday' use (but compatibility is broken for people who have
sub-classed either SAXHandler or SAXBuilder - and some methods have been 
deprecated on SAXBuilder and others have been renamed with the old names 
deprecated too).

The performance results are more effective than I expected. See: 
https://github.com/hunterhacker/jdom/issues/52#issuecomment-2844750
where you can see that the code now re-uses the parser and the whole 
process completes in a quarter of the previous time.

The changes are hard to describe in one place, but I have put together 
some documentation here: 
http://hunterhacker.github.com/jdom/jdom2/apidocs/org/jdom2/input/sax/package-summary.html#package_description

Finally, I have updated the performance page too: 
http://hunterhacker.github.com/jdom/jdom2/performance.html

You can see that the SAX builder has now re-taken the lead from the StAX 
prcess.

Thanks

Rolf


On Sat, 19 Nov 2011 23:12:49 -0500, Rolf <[email protected]> wrote:
> Hi all.
>
> I am looking to run some ideas past the group. I see a number of
> problems with the SAXBuilder as it currently is. It is somewhat hard to
> describe them all, but, the bottom line is that I think the API should
> be changed for it in a smallish way that will affect people who use a
> custom SAXHandler, or those who hard-code a SAXParser Driver classname
> in the SAXBuilder constructor. I believe the vast majority of people use

> the default constructor, and do not subclass the SAXHandler so this
> change will affect only a small subset of JDOM users.
>
> So, here are the problems I see, in addition to the bug related to
> long-living memory references.
>
>
> Problem 1: SAXParser creation
>
> JDOM uses 3 mechanisms to create a SAX parser:
> 1. if the user specifies a specific SAX 'Driver' classname
> 2. else falls-back to JAXP
> 3. else falls back to a 'default' SAX Driver (xerces)
>
> I believe that the 'default' fall-back should be removed because if JAXP

> fails there's nothing. At minimum, JAXP will find the parser embedded in

> the Java runtime, and the 'default' fallback will never happen. Put
> another way, if JAXP fails, there is no reason to expect
> that the 'default' "org.apache.xerces.parsers.SAXParser" will work
> (because if you have org.apache.xerces.parsers.SAXParser then you also
> have a working JAXP parser....)
>
> I also believe the user-specified 'driver' mechanism should be replaced
> with a straight XMLReaderFactory instance. This makes the JDOM user
> responsible for creating the factory. It also adds the ability for the
> user to have just a single Factory instance and not have JDOM creating a

> new instance each time a new SAXBuilder is created. This will give the
> user the opportunity to improve performance that JDOM cannot do.
> XMLReaderFactory is part of SAX2.0 and has been in Java since at least
> Java 1.4. It is the 'correct' way to get an XMLReader instance. Also,
> new JDOM users will not be confused by this string value, wheras
> XMLReaderFactory is a real, standard, and well documented entity.
>
> Further, there should be no fallback mechanism: if the user manually
> provides a XMLReaderFactory and it fails then it should all fail. If the

> user uses JAXP (the default), and JAXP fails then we fail. In the Java5+

> world JDOM should not need to be 'molly-coddling' the JAXP process.
> Also, we should not be useing such outdated mechanisms as direct SAX
> driver classes.
>
> This change would 'neaten' up the API for creating SAXBuilders:
> 1. you either use the 'normal' JAXP process, or...
> 2. you use the standard non-JAXP mechanism XMLReaderFactory
>
>
> Problem 2: Parser reuse.
>
> XMLReader reuse is much more efficient than creating a new parser for
> each JDOM build. There have been a few attempts to improve the parser
> reuse in JDOM, but it could be taken even further by only re-configuring

> the XMLReader when the SAXBuilder configuration changes. In a typical
> use where the configuration is unchanged between consecutive JDOM builds

> then there does not need to be any reconfiguration at all.
>
>
> Problem 3: The long-linked memory
>
> The fix for this is probably going to need a 'reset' method on the
> SAXHandler that de-references the Document that was last parsed. This in

> turn will require an API change on SAXHandler.
>
> Problem 4: SAXHandler sub-classing
>
> SAXHandler subclassing allows for custom event handling, but, in order
> to use a custom SAXHandler you also have to subclass SAXBuilder and
> override the createContentHandler() method. This is a cumbersome (and
> not well documented) mechanism.
>
>
>
> What with these (at least) 4 issues with SAXBuilder it makes sense to
> change the API slightly to accomodate the 'new' way of doing things.
> This will impact the way that subclassing is done, and will impact those

> who use a non-JAXP SAX parser.
>
> If these changes (or others like them) need to happen (and I think they
> do), then it makes sense to do it right, and comprehensively.
>
> I am going to play with the code a little to get an idea of what can be
> done, but I am looking for any ideas, suggestions, criticisms.
>
> I have already made some changes affecting the JDOM2 API but I think
> this could be one of those changes that makes a real difference (for the

> better).
>
> Rolf
>
>
> On 18/11/2011 7:32 PM, Rolf wrote:
>> I have updated the issue with some performanc numbers for some
different
>> conditions.
>>
>> Have a look at: https://github.com/hunterhacker/jdom/issues/52
>>
>> It seems to indicate that fixing the 'back to raw JAXP for each loop'
>> will only save a little time, but parser reuse saves a lot.
>>
>> Need to implement both options, I think, implement SAXFactory caching
as
>> well as better memory management on Parser reuse.
>>
>> Out of interest, I thought the default setting for parser reuse was
>> 'false', but it is true. XMLReaders will be reused unless you
explicitly
>> setReuseParser(false);
>>
>> This in turn means that my comments about 'normal' process should be
>> reversed, the normal case for this bug condition is that we keep a
>> reference from the SAXBuilder to the Document for as long as the
>> SAXBuilder is active, and not used to rebuild another document.
>>
>> Thanks
>>
>> Rolf
>> _______________________________________________
>> To control your jdom-interest membership:
>> http://www.jdom.org/mailman/options/jdom-interest/[email protected]
>>
>
> _______________________________________________
> To control your jdom-interest membership:
> http://www.jdom.org/mailman/options/jdom-interest/[email protected]
_______________________________________________
To control your jdom-interest membership:
http://www.jdom.org/mailman/options/jdom-interest/[email protected]
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.