I've looked a little bit into this but I'm still in the process of learning how the PropertyCache works.
I've done some statistics running a 100 page document (XSLT 1.0 spec in FO) multiple times: - New CacheEntry instances: 2410 - Cloned CacheEntry instances: 1010616 - Cloned CacheEntry instances with cleared reference [1]: 957771 - CacheEntry instances run through finalize(): 1006688 [1] This is the number of calls to the CacheEntry(CacheEntry, CacheEntry) constructor while the weak reference is actually null or the reference cleared already. Somehow (I haven't found the cause, yet) more than 90% of all CacheEntries are created without carrying a payload. This is very wrong. Another thing that bugs me: New cleaner threads are spawned dozens of times per second. Starting new threads is an expensive operation which is why applications like web containers pool threads. Looks like this is necessary here, too (see util.concurrent). However, my thinking rather goes in the direction of having one cleaner thread that goes through the ReferenceQueue (like Batik does it). But that will probably mean a doubly-linked list. Not sure, yet. I will try to find out some more... Jeremias Maerki On 14.11.2007 11:34:53 Chris Bowditch wrote: > Andreas L Delmelle wrote: > > Hi Andreas, > > > > > > > A splendid idea! > > I already thought my approach to be lacking somewhere, although it was > > too late last night to see where exactly. First off, the flag should, > > of course be declared 'volatile'. If not, then there is no guarantee a > > thread will see the most recent state. More importantly, there is the > > matter of cleanups that were already running at the time rehash() > > started acquiring its locks, as you point out. > > > > Introducing another dummy Object to synchronize on, seems like a very > > clean solution. The flag could still be used to avoid unnecessary > > cleanups or rehashes from being started. Synchronizing on a mutual > > object would still launch them, but they would merely have to wait. > > I'm not sure another object to synchronize on is required as the 2 > threads both already synchronize on the segments. I'm not familar with > the PropertyCache and I was expecting you to say that the rehash method > couldn't start whilst existing cleanups were running because of the sync > on segments. But I guess if that was working then we wouldn't need the > boolean flag either :-/ > > It's not clear to me from a quick glance at the code exactly what > segments within the Property Cache are, but gut feel is that > synchronization between the 2 threads needs more work. For now I will > just leave the null check in place since I don't have time to persue > this issue. > > > > > Regarding your observation of the OutOfMemoryError: this might need > > investigating. Do you have any indication as to which types of objects > > are leaking? > > Yes I have been running a profiling tool on FOP this morning and > discovered that the PropertyCache$CacheEntry inner class is the one that > seems to grow and grow (its +89,000 instances after 1100 documents), but > you knew that already ;) > > Chris >
