I am trying to add javaeditor to my program to extend the program at runtime. Everything works fine, except when you use the program as a whole (I imitated 1000-10000 compilers). Memory usage is increasing and increasing, it seems that a memory leak is occurring.
In my program, the class is loaded, the constructor starts and the class is unloaded (no remaining instance and the Loader class become invalid because I set the pointer to zero). I analyzed the process using JConsole, classes are unloaded when the garbage collector runs.
I made a heapdum by opening it in a memory analyzer, the problem seems to be inside java.net.FactoryURLClassLoader (in the object com.sun.tools.javac.util.List). Since (com.sun.tools.javac) is part of the JDK, not the JRE, and SystemToolClassLoader is a FactoryURLClassLoader object, I would find a leak somewhere there. The number of loaded classes in SystemToolClassLoader increases from 1 to 521 the first time the compiler is started, but remains unchanged.
So, I have no idea where it is leaking, is there a way to reset SystemToolClassLoader? How could I pinpoint a leak.
EDIT: Well, I found out that this also happens in a very simple example. So it seems like this is part of the compilation, I don't need to load the class or instantiate it:
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) {
e.printStackTrace();
}
}
}
public static void compile() throws IOException, InstantiationException, IllegalAccessException, ClassNotFoundException
{
File source = new File( "src\\Example.java" );
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();
}
}