Details
-
Type: Bug
-
Status: Closed
-
Priority: Major
-
Resolution: Fixed
-
Affects Version/s: 1.2.2
-
Fix Version/s: 1.3
-
Component/s: Converters
-
Labels:None
Description
I was experiencing the same problem as Rene, i.e. getting a PermSpace OutOfMemoryError with pre-1.2.2 version. But when I upgraded to the 1.2.2 version (where the String-cache is kept in normal memory instead of Perm Space), I instead started getting OutOfMemoryError in the Old Space !!
After looking at the bug-fix code I realized that it indeed causes this OOM. The problem is that the WeakHashMap will never let the Strings be GCd, since it stores the Strings as both key and value. Since the value in a WeakHashMap is hard-linked (unlike the key), it can never be GCd - and thus eventually lead to a OOM.
See "Implementation note" on http://java.sun.com/javase/6/docs/api/java/util/WeakHashMap.html .
I'm also wondering a bit about the need for this caching? I can only see a few pros with it (rare XML-deserializations, with mostly the same XML-data), but more cons.
E.g. we use XStream for inter-server communication, where the deserialized XML-object only lives during a <1 second request, in this case caching any xml data is counter productive - just leading to unneceassary full GCs as Old Space fills up. (We will now plug our own StringConverter, with no caching, as work.-around)
A solution to the WeakHashMap problem would be to wrap the values in a WeakReference -thus making it egible for GC.
Issue Links
- is superceded by
-
XSTR-604 JVM stalls due to StringConverter when using a single long running instance of XStream
Hi Frederik,
thanks for heads-up. The main reason for the cache are strings that are used as enums. This is quite common for data kept in DBs. Without the caching all those strings will no longer be shared and consume quite a lot of unnecessary memory. Remember, that XStream tries to work optimal in various scenarios. Your solution to register a non-caching StringConverter is completely valid. But you should benchmark it ... for me the cached version was often faster (see code in svn -> benchmark/test).
I changed the impl now using weak references for the value also, so they should be catched by the GC now.