在應用程序中,我一再創造GroovyShell的實例,對它們執行自定義腳本。這樣做時,我遇到了Java 6和Java 7中的perm gen空間被填滿並且類不會被卸載的問題。我正在使用Groovy 2.4.7。重複使用Groovy的炮彈導致PermGen的空間充滿
import groovy.lang.GroovyShell;
public class Demo {
public static void main(String[] args) throws Exception {
for (int i = 0; i < 10000000; i++) {
GroovyShell gs = new GroovyShell();
Object result = gs.evaluate(" 'Hello, World';");
assert result.equals("Hello, World");
}
}
}
我使用以下VM參數:這個問題可以用下面的代碼進行復制
-verbose:class -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+CMSClassUnloadingEnabled -XX:+ExplicitGCInvokesConcurrentAndUnloadsClasses -XX:+TraceClassUnloading -XX:MaxPermSize=16M -XX:+UseConcMarkSweepGC -XX:+ExplicitGCInvokesConcurrent -XX:+PrintGCDetails -XX:-UseParNewGC
當我執行從上面的測試,PermGen的是滿後比2000年小迭代。另外,手動觸發GC不起作用。
有沒有辦法在這裏強制卸載類或者使得類是從PermGen的空間刪除觸發GC?
謝謝@尼古拉斯!我用Java 6和7測試了這個,並且這兩個類都卸載了兩個變體版本(並且也在多線程場景中)。不過,我會在Groovy Jira上提出一個缺陷,因爲在我看來,這應該由Groovy本身來處理,而不是由其用戶來處理。 –