内存泄漏示例 - 引用和对象

Memory Leak Example -references and objects

我有以下 method.Suppose 我从 class B 调用了 A.m1() 10,000 次。 因此,所有 10,000 个 MyObj 对象都将被垃圾回收,因为它们的范围仅在 m1() 方法内。 没有内存泄漏?

class A {
    String m1() {
        MyObj obj = new Mybj();
    }
}

我在下面称呼它

class B {
    void m2() {
        String s = classAObj.m1();
    }
}

我认为您具有 C++ 背景。在 Java 中,由于其垃圾收集系统,很难出现内存泄漏。垃圾收集可能会变得复杂,但基本思想是有一个程序不断 运行 在后台寻找堆中未使用的对象,当它找到一个时,它会删除它。因此,当您退出 m1() 方法时,没有对新 Mybj() 对象的引用,因此垃圾收集器将其删除。

方法中创建的引用在超出范围时最终会被垃圾回收。但这不一定立即发生。

这里有一个展示引用收集的demo。但首先 一些术语。

  • 硬引用 - 对 object 的正常引用将在
    附近,直到它被垃圾收集。这些是 object 创建的
    的典型实例值。
  • 弱引用 - 指向与硬引用相同 object 的引用。
    当垃圾收集硬引用时,也会收集关联的弱引用。

这是如何工作的。

  • 方法 m1 被调用 n 次,每次都创建 A 实例的弱引用并 return 调用它。
  • 然后将其添加到列表中。
  • 一旦硬引用被垃圾回收,引用相同object的弱引用也将被回收
  • 当尝试检索其关联的
    object.
  • 时,弱引用将 return 为 null
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;

public class GarbageCollection {
    
    public static void main(String[] args) {
        // get out of static context
        new GarbageCollection().start();
    }
    public void start() {
        
        int n = 10_000;
        List<WeakReference<A>> weak = new ArrayList<>();

通过调用 m1 和 return 引用来创建 An 弱引用。 然后它添加到 List.

        for (int i = 0; i < n; i++) {
            WeakReference<A> wk = m1();
            weak.add(wk);
        }

现在遍历弱引用列表,看看有多少是空的。 预计为零
,因为垃圾收集器尚未运行。在 m1 中创建的所有那些 A 分配仍然潜伏在堆中。

        int count = 0;
        for (WeakReference<A> wk : weak) {
            if (wk.get() == null) {
                count++;
            }
        }
       
        System.out.println(count); // probably zero

现在重复相同的过程,但明确调用垃圾收集器。

        count = 0;
        System.gc();
        for (WeakReference<A> wk : weak) {
            if (wk.get() == null) {
                count++;
            }
        }

此时,count 应该是 non-zero(或者 n 小值 n)到
显示部分或全部 object 已收集。

        System.out.println(count);
    }
    
    public WeakReference<A> m1() {
       A a = new A();
       return new WeakReference<>(a);
    }
}

class A {
}