【问题标题】:Will this cause memory leak [duplicate]这会导致内存泄漏[重复]
【发布时间】:2014-06-19 12:17:05
【问题描述】:

我是 Java 垃圾收集的新手,想知道以下代码是否会导致 Java 中的内存泄漏。为什么或者为什么不?谢谢。

class ListNode {
    int value;
    ListNode next;

    public ListNode(int value) {
        this.value = value;
        next = null;
    }
}

public class Test() {

    static void tryCreateMemoryLeak() {
        ListNode l1, l2;
        for (int i = 0; i < 1000000; i++) {
            l1 = new ListNode(1);
            l2 = new ListNode(2);

            // create a circle here
            // will this circle be reclaimed? if do, when?
            l1.next = l2;
            l2.next = l1;
        }
    }

    public static void main(String[] args) {
        tryCreateMemoryLeak();
    }

}

【问题讨论】:

标签: java memory memory-leaks garbage-collection


【解决方案1】:

GC 识别偶数圆。一旦你不再引用这个圈子(例如离开范围),GC 最终会释放内存。在 Java 中创建内存泄漏是……很困难的。但也不是不可能(取决于内存泄漏的实际定义)。

【讨论】:

    【解决方案2】:

    循环引用不会导致内存泄漏。当循环引用链中不再存在对任何对象的实时引用时,这些对象将进行垃圾回收。实际垃圾回收发生的时间取决于实现。

    【讨论】:

      【解决方案3】:

      由于 Java JVM 的 GC 是一个跟踪和标记和清除垃圾收集器,而不是一个引用计数器,所以在 Java 中纯粹通过循环引用是不可能造成内存泄漏的。

      这样做的原因是 A 将引用 B,B 将引用 A,但没有其他对象将引用 A 或 B,因此将 A 和 B(在标记阶段)都标记为符合垃圾回收条件。

      JVM 的 GC 将堆中的所有对象标记为可收集,从它的根开始跟踪,例如静态变量、类加载器等,将此跟踪可访问的所有对象标记为不可收集,因此永远不会到达 A 或 B 实例你分配的。因此,JVM 的 GC 会检测到 A 和 B 符合垃圾回收条件并回收它们的内存。

      【讨论】:

        【解决方案4】:

        【讨论】:

          【解决方案5】:

          内存泄漏是保留对不应再引用的内容的实时引用(错误地)。

          您不会通过创建一个复杂的引用网络来欺骗任何现代垃圾收集器。垃圾收集器已经(并且已经存在了很多年)足够成熟,可以可靠地处理循环引用。

          根据经验:今天的内存泄漏绝不是由垃圾收集器无法收集未引用的东西引起的 - 如果某些东西没有被收集,总会有一个(通常隐藏得很好)实时引用.

          【讨论】:

          • 实际上,你可以通过创建循环引用在 ARC 中产生内存泄漏。这完全取决于 GC 使用的是哪种垃圾收集算法。
          • @DavidXu 如果被圈子愚弄,我不会认为它是现代 GC。你?。顺便说一句,这个问题被标记为“java”,并且循环依赖在 java 中非常丰富,即使在 JDK 中也是如此。所以任何不处理循环依赖的 GC 都将被限制在 java 中一个非常小的问题域。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多