当前位置: 首页 > 知识库问答 >
问题:

Java内存泄漏:为什么不可达对象没有被收集?

益稳
2023-03-14

我试图找到一个解决JDK Nashorn错误JDK-8229011。

我使用错误票证中链接的脚本重现了错误,并进行了几次堆转储。我使用 JProfiler 和 Eclipse Memory Analyzer 来查找问题的根源。但是,我总是以无法访问的路径结束,我不明白为什么对象没有被垃圾回收。AFAIS 没有终结者可以让他们活着。如果我在 JProfiler 中打开堆转储而不禁用“转储上的完整 GC”,JProfiler 甚至会丢弃无法访问的对象。但 GC 本身不会。我用 G1 GC 进行了测试,但 CMS 也是如此。

使用任何JDK,您可以在1-2分钟内获得示例转储

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

我在寻找一些线索,是什么让这些物体存活。

共有1个答案

文华美
2023-03-14

我不知道发生了什么,但是Eclipse内存分析器的最新开发版本给出了一些有趣的发现。快照比较-加载堆转储1、加载堆转储2,运行“通过快照比较的泄漏嫌疑:包括泄漏嫌疑和来自比较两个快照的系统概述”

问题嫌疑人1

“”加载的“java.lang.ClassValue$ClassValueMap”的一个实例占用了809280(19.48%)字节。内存累积在“java.lang.ClassValue$ClassValueMap”的一个实例中,由“”加载,占用809280(19.48%)字节

关键词Java . lang . class value $ class value map

组件报告还说:

弱参考统计

总共发现了10,007个java.lang.ref.的弱引用对象,它们弱引用了6,969个对象。6个总计192 B的对象仅通过弱引用被保留(保持活动)。可能的内存泄漏5,785个总计124.4 KB的对象被弱引用,也通过弱引用被强烈保留(保持活动)。

详情 »

 类似资料:
  • 本文向大家介绍什么是内存泄漏?相关面试题,主要包含被问及什么是内存泄漏?时的应答技巧和注意事项,需要的朋友参考一下 答:一般我们所说的内存泄漏指的是堆内存的泄漏。堆内存是程序从堆中为其分配的,大小任意的,使用完后要显示释放内存。当应用程序用关键字new等创建对象时,就从堆中为它分配一块内存,使用完后程序调用free或者delete释放该内存,否则就说该内存就不能被使用,我们就说该内存被泄漏了。

  • 本文向大家介绍Java 内存泄漏,包括了Java 内存泄漏的使用技巧和注意事项,需要的朋友参考一下 在Java中,垃圾回收(析构函数的工作)是使用垃圾回收自动完成的。但是,如果代码中有引用它们的对象怎么办?它无法取消分配,即无法清除其内存。如果这种情况一再发生,并且创建或引用的对象根本没有被使用,它们就会变得无用。这就是所谓的内存泄漏。 如果超过了内存限制,则程序将通过抛出错误(即“ OutOfM

  • 我正在玩rxjava,发现如果在活动被销毁之前没有完成订阅,则存在内存泄漏的风险,因为“可观察对象保留对上下文的引用”。如果订阅没有取消订阅,则此类情况的演示之一如下所示。已销毁(来源:https://github.com/dlew/android-subscription-leaks/blob/master/app/src/main/java/net/danlew/rxsubscriptions

  • 本文向大家介绍内存泄漏和内存溢出有什么区别相关面试题,主要包含被问及内存泄漏和内存溢出有什么区别时的应答技巧和注意事项,需要的朋友参考一下 内存泄漏是分配的内存无法释放,导致一直占用内存空间,最终可能引发内存溢出 内存溢出是申请或使用内存超出可以分配的内存时(例如往一个整形空间存放长整形的数据) 参考文章

  • 本文向大家介绍内存泄漏和内存溢出是什么?一般怎么处理内存泄漏?相关面试题,主要包含被问及内存泄漏和内存溢出是什么?一般怎么处理内存泄漏?时的应答技巧和注意事项,需要的朋友参考一下 (1)内存溢出(OOM)和内存泄露(对象无法被回收)的区别。 (2)引起内存泄露的原因 (3)内存泄露检测工具 ------>LeakCanary 内存溢出 out of memory:是指程序在申请内存时,没有足够的内

  • 问题内容: 我发现使用是众所周知的与相关的内存问题。 使用中是否存在内存泄漏? 如果是,解决方法是什么? 以下链接显示了Java中子字符串的正确用法。 http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4513622 另外一个博客谈论子字符串中可能的MLK。 http://nflath.com/2009/07/the-dangers-of- st