Java内存泄漏?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java内存泄漏?相关的知识,希望对你有一定的参考价值。

我的理解是Java没有内存泄漏。通过内存泄漏,我的意思是你不能再访问的内存(不是内存,你可以,但你没有)。这是C:https://en.wikipedia.org/wiki/Memory_leak#A_simple_example_in_C中的一个例子

一位朋友把我和这两篇文章联系起来:

但是,我没有看到任何迹象表明Java实际上是在泄漏内存,只是存在程序员错误,例如:

  • 存储太多不必要的数据(比如你一直追加的列表)
  • 没有足够的内存(并需要更多的RAM /堆空间)
  • 本机代码无法正确管理其内存
  • 不关闭流或数据库等本机资源
  • 可能是JVM中需要修复的错误

他还提到了循环引用,但我相信Java也会因为跟踪垃圾收集器而处理这些问题。

我这是对的吗?除了我列出的问题,Java是否有任何“真正的”内存泄漏?

答案

java中的内存泄漏是通过将引用保留在您认为已删除的对象中引起的,但是您保留了一个或多个引用,这些引用从根GC(例如静态对象)提供了该对象的路径。这意味着JVM必须假设将来可能会访问该对象。它不知道程序员不再需要该对象。

这有点像忘记在C / C ++中释放内存。这里的区别在于您忘记删除对它的引用而不是释放对象本身。

在这里阅读更多相关信息:http://www.w3resource.com/java-tutorial/garbage-collection-in-java.php

你可以在这里看到内存泄漏的例子:Creating a memory leak with Java

另一答案

当你说“......我没有看到任何迹象表明Java实际上正在泄漏内存,只是存在程序员错误......”时,你可以对C中缺少的内存释放说同样的话。但是,它是一个记忆泄漏。

如上所述,在Java上下文中,内存泄漏是应用程序不再使用某些对象的情况,但垃圾收集器(GC)无法将它们识别为未使用并释放它们。

例如,忘记关闭已打开的流:

class MemoryLeak {

    private void startLeaking() throws IOException {
        StringBuilder input = new StringBuilder();
        URLConnection conn = new URL("www.example.com/file.txt").openConnection();

        BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8));        

        while (br.readLine() != null) {
            input.append(br.readLine());
        }
    }

    public static void main(String[] args) throws IOException {
        MemoryLeak ml = new MemoryLeak();
        ml.startLeaking();
    }
}

取自:https://github.com/stas-slu/memory-leak-with-java/tree/master/src/com/memoryleak

以上是关于Java内存泄漏?的主要内容,如果未能解决你的问题,请参考以下文章

FragmentStatePagerAdapter 内存泄漏(带有 viewpager 的嵌套片段)

带有 UI 和内存泄漏的保留片段

在片段中保存活动实例:是否会导致内存泄漏?

片段 - 全局视图变量与本地和内部类侦听器和内存泄漏

iPhone内存泄漏问题?

使用导致内存泄漏的音频片段