Speicherverlust bei Verwendung des JDK-Compilers zur Laufzeit

Ich versuche, meinem Programm einen Java-Editor hinzuzufügen, um das Programm zur Laufzeit zu erweitern. Es funktioniert alles einwandfrei, außer wenn Sie das Programm ausgiebig verwenden (ich habe 1000-10000 Compiler-Ausführungen simuliert). Die Speichernutzung steigt und steigt, es sieht so aus, als gäbe es einen Speicherverlust.

In meinem Programm wird die Klasse geladen, der Konstruktor ausgeführt und die Klasse entladen (keine verbleibende Instanz und der classLoader wird ungültig, wenn ich den Zeiger auf null setze). Ich habe den Prozess mit JConsole analysiert, die Klassen werden entladen, wenn der Garbage Collector ausgeführt wird.

Ich habe einen Heapdum in Memory Analyzer geöffnet, das Problem scheint in java.net.FactoryURLClassLoader (in einem com.sun.tools.javac.util.List-Objekt) zu liegen. Da (com.sun.tools.javac) Teil des JDK ist und nicht in der JRE und der SystemToolClassLoader ein FactoryURLClassLoader-Objekt ist, würde ich das Leck irgendwo dort finden. Die Anzahl der geladenen Klassen im SystemToolClassLoader steigt von 1 auf 521, wenn ich den Compiler zum ersten Mal ausführe, aber danach gleich bleibe.

Ich habe also keine Ahnung, wo das Leck ist. Gibt es eine Möglichkeit, den SystemToolClassLoader zurückzusetzen? Wie könnte ich das Leck genauer lokalisieren.

EDIT: Okay, ich habe herausgefunden, dass es auch in einem sehr sehr einfachen Beispiel vorkommt. Es scheint also ein Teil der Kompilierung zu sein, ich muss die Klasse nicht laden oder instanziieren:

import java.io.File;
import java.io.IOException;
import java.util.Arrays;

import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;


public class Example {   

public static void main(String[] args)
{
    for (int i =0; i<10000;i++){
        try {
            System.out.println(i);
            compile();
        } catch (InstantiationException | IllegalAccessException
                | ClassNotFoundException | IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}

public static void compile() throws IOException, InstantiationException, IllegalAccessException, ClassNotFoundException
{
    File source = new File( "src\\Example.java" ); // This File
    JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
    StandardJavaFileManager fileManager = compiler.getStandardFileManager( null, null, null );
    Iterable<? extends JavaFileObject> units;
    units = fileManager.getJavaFileObjectsFromFiles( Arrays.asList( source ) );
    compiler.getTask( null, fileManager, null, null, null, units ).call();
    fileManager.close();
}

}

Antworten auf die Frage(5)

Ihre Antwort auf die Frage