当我运行以下 JUnit 测试时,java 进程的内存不断增加。几个小时后,它使用了 2go 以上。但是,当我查看 jvisualvm 时,堆和 permgen 大小是稳定的,我看不到任何泄漏。测试运行-Xmx32m
public class TestCat {
public static class A { }
@Test
public void testCategory() {
for(;;) {
GroovyCategorySupport.use(A.class, new Closure<Object>(null) {
public Object call() { return null; }
});
}
}
}
我已经用 Groovy 2.4.7、Windows 和 JRE1.7_80、MacOS 和 JRE1.7_60 对其进行了测试。我无法使用 MacOS 和 JRE 1.8.0_91 重现此错误
我想这与 JRE1.7 中的一个错误有关,我正在寻找一种方法来缓解这个问题:
- 我的测试可能是错的?如何在不泄漏堆空间或 permgen 空间的情况下泄漏“系统”内存?
- 它是 Groovy 和 JRE 1.7 之间的“已知”错误或不兼容吗?
- 如何使用 1.7 jre 的 groovy 类别而不会遭受这种内存泄漏?
编辑
我可以通过调用来重现这个错误VMPluginFactory.getPlugin().invalidateCallSites()
,它用这个“纯java”单元测试翻译:
public class TestSwitchPoint {
@Test
public void testSP() {
SwitchPoint switchPoint = new SwitchPoint();
for(;;) {
SwitchPoint old = switchPoint;
switchPoint = new SwitchPoint();
SwitchPoint.invalidateAll(new SwitchPoint[]{old});
}
}
}
其实只要new SwitchPoint()
够用。