A patch for CycleBreaker (which secures access to _threadHash with an ReentrantReadWriteLock) is attached to CASTOR-2746 [1].

Cheers,
Torsten

[1] http://jira.codehaus.org/browse/CASTOR-2746

On 23.06.2009, at 22:09, Torsten Juergeleit wrote:

CycleBreaker claims to be a "thread-safe detection of cyclic calls" but it's implementation isn't thread-safe. This is because it uses as "_threadHash" an unsynchronized instance of IdentityHashMap.

<quote from javadoc of IdentityHashMap >
Note that this implementation is not synchronized. If multiple threads access this map concurrently, and at least one of the threads modifies the map structurally, it must be synchronized externally. (A structural modification is any operation that adds or deletes one or more mappings; merely changing the value associated with a key that an instance already contains is not a structural modification.) This is typically accomplished by synchronizing on some object that naturally encapsulates the map. If no such object exists, the map should be "wrapped" using the Collections.synchronizedMap method.
</quote>

This seems to be a similar issue as with XMLClassDescriptorResolverImpl [1] which needed a ReentrantReadWriteLock as well.

I will come up with a patch.

Cheers,
Torsten

[1] http://jira.codehaus.org/browse/CASTOR-2019


On 23.06.2009, at 20:26, Godmar Back wrote:


Oh, the irony of a class called "cycle breaker" being involved in a memory leak!

From a brief look at this class: 
http://jira.codehaus.org/secure/attachment/27944/CycleBreaker.java

it seems the problem is caused by calls to "startingToCycle" not being matched with calls to "releaseCycleHandle". You may wish to examine the code for this situation.

 - Godmar

On Tue, Jun 23, 2009 at 2:11 PM, Harry Hehl <[email protected] > wrote:
Hello

With castor 1.2 and 1.3 if equals/hashcode generation is enabled the
generated equals() method calls
org.castor.core.util.CycleBreaker.startingToCycle .

org.castor.core.util.CycleBreaker contains private static
IdentityHashMap _threadHash = new IdentityHashMap();

During testing it was discovered the application was leaking memory. It
was tracked to _threadHash referencing many objects when they are no
longer referenced anywhere else.

Why would an object not be removed from _threadHash?  Not generating
hash/equals methods eliminates the leak, but they are required by the
application.

Can this cycle breaker code be disabled? i.e. is it really necessary?

Thanks.


Reply via email to