sebthom/oval

High contention on ContextCache

Closed this issue · 4 comments

Validators are extensively used in my project and recently I've found that almost all my worker threads are blocked waiting for lock inside ContextCache.getFieldContext.

I started wondering what had caused that and here is what I have:
ContextCache.getFieldContext uses WeakHashMap inside to cache FieldContext objects, however, according to https://docs.oracle.com/javase/7/docs/api/java/util/WeakHashMap.html

The value objects in a WeakHashMap are held by ordinary strong references. Thus care should >be taken to ensure that value objects do not strongly refer to their own keys, either directly or >indirectly, since that will prevent the keys from being discarded.

'FieldContext` has a strong reference to its key

public static FieldContext getFieldContext(final Field field) {
      synchronized (FIELD_CONTEXTS) {
         FieldContext ctx = FIELD_CONTEXTS.get(field);
         if (ctx == null) {
            ctx = new FieldContext(field);
            FIELD_CONTEXTS.put(field, ctx);
         }
         return ctx;
      }
}

Moreover, FieldContext calls SerializableField.getInstance, which in turn has the same pattern for caching. The same applies to some other ContextCache static methods.

So since we don't truly have any gain from using WeakHashMap here, would it be possible to replace these caches with something more performant in a concurrent environment, for example ConcurrentHashMap?

The reason why WeakHashMap is used is to allow classes to be unloaded/reloaded. E.g. in a JEE Server where you partially redeploy an EAR (replacing just a module, like an EJB/WAR). Otherwise classes may never be GCed. Maybe we can make the cache implementation to be used configurable.

I understand the intention, but unfortunately we have a memory leak here and those classes are never GCed due to the bug described above.

Can you give the latest 2.0.0-SNAPSHOT a try. You can find the snapshot builds at https://github.com/sebthom/oval/tree/mvn-snapshots-repo/net/sf/oval/oval/2.0.0-SNAPSHOT

Closing for now. Please reopen if problem persists.