Fix memory leak by disposing a classloader. The real issue though is located in TypeInfoParser, that has WeakHashMap with values referencing keys.

This commit is contained in:
Maxim Shafirov
2012-02-02 20:35:15 +04:00
parent 14ab62cf7a
commit 04b0699cd5
4 changed files with 28 additions and 9 deletions
@@ -6,7 +6,7 @@ import org.jetbrains.annotations.NotNull;
* @author yole
*/
public class GeneratedClassLoader extends ClassLoader {
private final ClassFileFactory state;
private ClassFileFactory state;
public GeneratedClassLoader(@NotNull ClassFileFactory state) {
this(state, GeneratedClassLoader.class.getClassLoader());
@@ -26,4 +26,8 @@ public class GeneratedClassLoader extends ClassLoader {
}
return super.findClass(name);
}
public void dispose() {
state = null;
}
}
@@ -174,7 +174,7 @@ public class CompileEnvironment {
}
private List<Module> runDefineModules(String moduleFile, ClassFileFactory factory) {
ClassLoader loader = myStdlib != null ? new GeneratedClassLoader(factory, new URLClassLoader(new URL[] {myStdlib}, AllModules.class.getClassLoader())) : new GeneratedClassLoader(factory);
GeneratedClassLoader loader = myStdlib != null ? new GeneratedClassLoader(factory, new URLClassLoader(new URL[] {myStdlib}, AllModules.class.getClassLoader())) : new GeneratedClassLoader(factory);
try {
Class namespaceClass = loader.loadClass(JvmAbi.PACKAGE_CLASS);
final Method method = namespaceClass.getDeclaredMethod("project");
@@ -188,9 +188,13 @@ public class CompileEnvironment {
ArrayList<Module> answer = new ArrayList<Module>(AllModules.modules);
AllModules.modules.clear();
return answer;
} catch (Exception e) {
}
catch (Exception e) {
throw new ModuleExecutionException(e);
}
finally {
loader.dispose();
}
}
public ClassFileFactory compileModule(Module moduleBuilder, String directory) {
@@ -91,10 +91,14 @@ public abstract class CodegenTestCase extends JetLiteFixture {
ClassFileFactory codegens = generateClassesInFile();
GeneratedClassLoader loader = new GeneratedClassLoader(codegens);
String fqName = NamespaceCodegen.getJVMClassName(JetPsiUtil.getFQName(myFile), true).replace("/", ".");
Class<?> namespaceClass = loader.loadClass(fqName);
Method method = namespaceClass.getMethod("box");
return (String) method.invoke(null);
try {
String fqName = NamespaceCodegen.getJVMClassName(JetPsiUtil.getFQName(myFile), true).replace("/", ".");
Class<?> namespaceClass = loader.loadClass(fqName);
Method method = namespaceClass.getMethod("box");
return (String) method.invoke(null);
} finally {
loader.dispose();
}
}
protected String generateToText() {
@@ -4,6 +4,7 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.local.CoreLocalFileSystem;
import gnu.trove.THashSet;
import junit.framework.TestCase;
import junit.framework.TestResult;
import junit.framework.TestSuite;
import org.jetbrains.jet.compiler.CompileSession;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
@@ -74,13 +75,19 @@ public class TestlibTest extends CodegenTestCase {
ClassFileFactory classFileFactory = session.generate();
GeneratedClassLoader loader = new GeneratedClassLoader(
final GeneratedClassLoader loader = new GeneratedClassLoader(
classFileFactory,
new URLClassLoader(new URL[]{ForTestCompileStdlib.stdlibJarForTests().toURI().toURL(), junitJar.toURI().toURL()},
TestCase.class.getClassLoader()));
JetTypeMapper typeMapper = new JetTypeMapper(classFileFactory.state.getStandardLibrary(), session.getMyBindingContext());
TestSuite suite = new TestSuite("StandardLibrary");
TestSuite suite = new TestSuite("StandardLibrary") {
@Override
public void run(TestResult result) {
super.run(result);
loader.dispose();
}
};
try {
for(JetFile jetFile : session.getSourceFileNamespaces()) {
for(JetDeclaration decl : jetFile.getDeclarations()) {