Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[mat-dev] Leak undetected by MAT

Hey
I've found a leak possible in OracleJDK/OpenJDK which is impossible to find using MAT
The bug report is https://bugs.openjdk.java.net/browse/JDK-8206208

I think the problem is that HPROF dump doesn't contain the information needed to find the leak, and therefor the problem is in HeapDumper.c code, and not in MAT

The leak is that Class::newInstance() is leaking the caller, since it is doing caller checks, and cache the caller forever (no WeakReference, which is the fix in my opinion)

For example, executing the following code:

package poc;

import java.io.ByteArrayOutputStream;
import java.lang.ref.WeakReference;
import java.net.URL;
import java.net.URLClassLoader;

public class Leak {
  public static void main(String[] args) throws Exception {
    WeakReference<ClassLoader> loader = getLoader();

    while (loader.get() != null) {
      System.gc();
      Thread.sleep(1000);
    }
  }

  public static void test() {
    try {
      // BUG(JDK-8206208): Leaks the caller in newInstanceCallerCache in Java9+
      ByteArrayOutputStream.class.newInstance();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  private static WeakReference<ClassLoader> getLoader() throws Exception {
    URL url = "" style="background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline">Leak.class.getProtectionDomain().getCodeSource().getLocation();
    URLClassLoader loader = new URLClassLoader(new URL[] {url}, null);
    Class<?> workerClass = Class.forName("poc.Leak", true, loader);
    workerClass.getDeclaredMethod("test").invoke(null);
    loader.close();
    return new WeakReference<>(loader);
  }
}

will leak forever under current Java9/10/11

So this leak is reported and hopefully fixed before Java11 release, but the problem is that its invisible under MAT.

Because when I try to query using OQL and find those "faulty" classes, I don't see any members of newInstanceCallerCache under it
But when I'm with a debugger I do see them.

I'm sending this email to make sure the problem is indeed in JDK core code,
As far as I understand the JDK does not dump class instances, and therefor we don't have the fields: http://hg.openjdk.java.net/jdk/jdk/file/9f62267e79df/src/hotspot/share/services/heapDumper.cpp#l1418

What do you think?

Back to the top