我正在尝试找到针对JDK Nashorn错误JDK-8229011的解决方法。
我用错误票证中链接的脚本重现了错误,并进行了几次堆转储。我使用了JProfiler和Eclipse Memory Analyzer 找到问题的根源。但是,我总是以无法到达的路径结束,而且我不明白为什么不对这些对象进行垃圾收集。 AFAIS没有终结器可以使它们存活。 如果我在JProfiler中打开堆转储而不禁用“ Dump上的完整GC”,JProfiler甚至会丢弃无法访问的对象。但是GC本身不会。我使用G1 GC进行了测试,但是使用CMS进行了测试。
通过使用以下设置运行以下脚本,您可以在1-2分钟内使用任何JDK> 8进行示例转储:-Xmx20M -XX:+HeapDumpOnOutOfMemoryError
public class TestJsMemLeak
{
public static final class JsJavaUtil
{
private long counter = 0;
public long testFunc()
{
return counter++;
}
}
public static void main(final String[] args) throws Exception
{
System.setProperty("nashorn.args", "--no-java -doe -ot=false --language=es6 --no-deprecation-warning --lazy-compilation=false");
for (long i = 0; true; ++i)
{
final ScriptEngine scriptEngine = new ScriptEngineManager().getEngineByName("nashorn");
scriptEngine.put("JsJavaUtil", new JsJavaUtil());
scriptEngine.eval("for (var i = 0; i < 10; ++i) {\n" + " JsJavaUtil.testFunc();\n" + "}");
System.gc();
if (i % 100 == 0)
{
System.out.println(Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory());
}
}
}
}
运行此操作将导致转储,其中包含约6-7 MB的java.lang.ClassValue $ ClassValueMap无法访问
我正在寻找一些提示,是什么使这些对象保持活动状态。
答案 0 :(得分:0)
我不知道发生了什么,但是latest development build of Eclipse Memory Analyzer给出了一些有趣的发现。 快照比较-加载堆转储1,加载堆转储2,运行 “快照比较可疑 :包括泄漏嫌疑人 和比较两个快照的系统概述。”
问题嫌疑人1
由“”加载的“ java.lang.ClassValue $ ClassValueMap”的一个实例占用+809,280(19.48%)字节。内存存储在一个由“”加载的“ java.lang.ClassValue $ ClassValueMap”实例中,该实例占用+809,280(19.48%)字节。
关键字 java.lang.ClassValue $ ClassValueMap
“组件”报告也显示:
参考统计不足
总共找到了10,007个java.lang.ref.WeakReference对象,其中几乎引用了6,969个对象。 总共192 B的6个对象仅通过弱引用保留(保留)。 可能会泄漏5785个对象,总计124.4 KB,可能会被弱引用,并且也会通过弱引用强烈保留(保持活动状态)。
详细信息»