From 3b3fee84d9e68c82b23bf8204466412d1ba41c5d Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Fri, 11 Jul 2014 21:37:10 +0200 Subject: [PATCH] clear zip file caches on low memory --- .../jps/incremental/IncProjectBuilder.java | 2 + .../org/jetbrains/jps/javac/JavacMain.java | 55 +++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/IncProjectBuilder.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/IncProjectBuilder.java index baa67a0216d8..88fdef9eaad2 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/IncProjectBuilder.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/IncProjectBuilder.java @@ -56,6 +56,7 @@ import org.jetbrains.jps.incremental.storage.BuildTargetConfiguration; import org.jetbrains.jps.incremental.storage.OneToManyPathsMapping; import org.jetbrains.jps.incremental.storage.OutputToTargetRegistry; import org.jetbrains.jps.indices.ModuleExcludeIndex; +import org.jetbrains.jps.javac.JavacMain; import org.jetbrains.jps.model.java.JpsJavaExtensionService; import org.jetbrains.jps.model.java.compiler.JpsJavaCompilerConfiguration; import org.jetbrains.jps.model.module.JpsModule; @@ -176,6 +177,7 @@ public class IncProjectBuilder { final LowMemoryWatcher memWatcher = LowMemoryWatcher.register(new Runnable() { @Override public void run() { + JavacMain.clearCompilerZipFileCache(); myProjectDescriptor.dataManager.flush(false); myProjectDescriptor.timestamps.getStorage().force(); } diff --git a/jps/jps-builders/src/org/jetbrains/jps/javac/JavacMain.java b/jps/jps-builders/src/org/jetbrains/jps/javac/JavacMain.java index c5b6d861a8e4..ac4f4a0b78fc 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/javac/JavacMain.java +++ b/jps/jps-builders/src/org/jetbrains/jps/javac/JavacMain.java @@ -452,4 +452,59 @@ public class JavacMain { } } + private static class ZipFileIndexCleanupDataHolder { + @Nullable + static final Method cacheInstanceGetter; + @Nullable + static final Method cacheClearMethod; + + static { + Method getterMethod = null; + Method clearMethod = null; + try { + //trying JDK 6 + clearMethod = Class.forName("com.sun.tools.javac.zip.ZipFileIndex").getDeclaredMethod("clearCache"); + clearMethod.setAccessible(true); + } + catch (Throwable e) { + try { + final Class cacheClass = Class.forName("com.sun.tools.javac.file.ZipFileIndexCache"); + clearMethod = cacheClass.getDeclaredMethod("clearCache"); + getterMethod = cacheClass.getDeclaredMethod("getSharedInstance"); + clearMethod.setAccessible(true); + getterMethod.setAccessible(true); + } + catch (Throwable ignored2) { + clearMethod = null; + getterMethod = null; + } + } + + cacheInstanceGetter = getterMethod; + cacheClearMethod = clearMethod; + } + } + + private static volatile boolean zipCacheCleanupPossible = true; + + public static void clearCompilerZipFileCache() { + if (zipCacheCleanupPossible) { + final Method clearMethod = ZipFileIndexCleanupDataHolder.cacheClearMethod; + if (clearMethod != null) { + final Method getter = ZipFileIndexCleanupDataHolder.cacheInstanceGetter; + try { + Object instance = getter != null? getter.invoke(null) : null; + clearMethod.invoke(instance); + } + catch (Throwable e) { + zipCacheCleanupPossible = false; + } + } + else { + zipCacheCleanupPossible = false; + } + } + } + + }