On 2011/01/11 16:21:50, scottb wrote:

Generally, can you justify this scheme?  I read the article, but I
still don't
understand the advantage of this approach over say, Map<ClassLoader,
?> where
the key is weak.

  Problem happens when you have reference from "value" to "key".
  For example, if you try to use WeakHashMap<ClassLoader,Class>, you
will have a memory leak. If you use WeakHashMap<Class,Method>, you also
will have a memory leak. This happens because there is HARD reference to
"key"
  So, if you need map like this, you have to isolate it in ClassLoader.
  In GWT Designer we need such maps, so we use ClassLoaderLocalMap.

  Here is full example.

public class ClassLoaderLocalMapTest {
  private static final boolean useCLLM = false;
  //private static final Map<ClassLoader, Object> weakMap = new
WeakHashMap<ClassLoader, Object>();
  private static final Map<ClassLoader, Object> weakMap =
      new ReferenceMap(AbstractReferenceMap.HARD,
AbstractReferenceMap.SOFT);

  public static void main(String[] args) throws Exception {
    String gwtPath = "C:/Work/GWT/gwt-2.1.1/gwt-user.jar";
    for (int i = 0; i < 100000; i++) {
      System.out.println(i);
      ClassLoader classLoader = new URLClassLoader(new URL[]{new
File(gwtPath).toURL()});
      Class<?> clazz =
classLoader.loadClass("com.google.gwt.user.client.EventListener");
      //Object value = new ClassWrapper(clazz);
      Object value = clazz;
      putValue(classLoader, i, value);
    }
  }

  private static void putValue(ClassLoader classLoader, int localKey,
Object value) {
    if (useCLLM) {
      ClassLoaderLocalMap.put(classLoader, localKey, value);
    } else {
      weakMap.put(classLoader, value);
    }
  }

  private static class ClassWrapper {
    Class<?> clazz;

    public ClassWrapper(Class<?> clazz) {
      this.clazz = clazz;
    }
  }
}

  Note, that if you put directly Class as value, it has reference on
ClassLoader and causes memory leak and it dies with OOME on 919
iteration. But if you use ClassLoaderLocalMap, then no memory leak and
it works as long as you want.
  But if you put wrapper of Class, then no memory leak.



Functionally, the biggest problem is that it looks like we were
holding
ModuleDefs with soft references, but now they're being held with weak
references, which will cause them to disappear too quickly.

  After additional thoughts I think that situation with ModuleDef is a
little different than in examples before.
ReferenceMap<ClassLoader,Map<String,ModuleDef>>(HARD,SOFT) will not
cause memory leak because GC will remove SOFT referenced module maps.
However once ClassLoader is gone (when use closes editor in GWT
Designer), we never will use its entry. So, SOFT and WEAK are same here.
And if it is in reality part of ClassLoader information why not express
this directly as ClassLoader local cache and prevent clearing caches in
other places?




http://gwt-code-reviews.appspot.com/1274801/show

--
http://groups.google.com/group/Google-Web-Toolkit-Contributors

Reply via email to