【问题标题】:Java memory leaks?Java内存泄漏?
【发布时间】:2016-10-21 20:34:36
【问题描述】:

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

一位朋友将我链接到这两篇文章:

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

  • 存储过多不必要的数据(例如您不断追加的列表)
  • 内存不足(需要更多 RAM/堆空间)
  • 本机代码无法正确管理其内存
  • 不关闭本机资源,例如流或数据库
  • 可能是 JVM 中需要修复的错误

他还提到了循环引用,但我相信 Java 也可以处理这些,因为它的跟踪垃圾收集器。

我在这方面是正确的吗?除了我列出的问题之外,Java 是否有任何“真正的”内存泄漏?

【问题讨论】:

标签: java memory-leaks


【解决方案1】:

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

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

在此处了解更多信息:http://www.w3resource.com/java-tutorial/garbage-collection-in-java.php

您可以在此处查看内存泄漏示例:Creating a memory leak with Java

【讨论】:

    【解决方案2】:

    当您说“...我没有看到任何迹象表明 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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-09-29
      • 2015-08-14
      • 2012-08-11
      • 2015-12-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多