【问题标题】:Could a hard-reference to WeakReference.get() object cause memory leak?对 WeakReference.get() 对象的硬引用会导致内存泄漏吗?
【发布时间】:2017-06-28 15:27:45
【问题描述】:

比方说,我们有一个很长的线程:

private static class MyRunnable implements Runnable {

    private final WeakReference<Context> contextRef;

    private MyRunnable(Context leakable) {
        contextRef = new WeakReference<>(leakable);
    }

    @Override public void run() {
        Context context = contextRef.get();
        if (context == null) return;
        //VERY LONG TASK
        //Would hard referencing context gotten from WeakReference.get() leak memory?
        //Should contextRef be called each time context is needed?
    }
}


private void startThread() {
    new MyThread(this, new MyRunnable(this)).start();
}

问题本身就说明了一切:

-从 WeakReference.get() 获得的硬引用上下文会泄漏内存吗?

-是否应该在每次需要上下文时调用 contextRef 以避免泄漏?

-WeakReference.get()方法通过JNI调用native方法,get()方法调用开销大​​吗?

【问题讨论】:

    标签: java multithreading performance memory-leaks weak-references


    【解决方案1】:

    从 WeakReference.get() 获得的硬引用上下文会泄漏内存吗?

    如果某个对象仍在使用中,我不会认为这是内存泄漏。如果您保留不需要的内存,这可能是个问题。您可以在不再需要时清除/丢弃字符串引用。

    对对象进行弱引用不会改变任何强引用的行为。

    是否应该在每次需要上下文时调用 contextRef 以避免泄漏?

    仅当您在执行此操作时对它消失感到满意时。如果你需要它来返回对象(甚至在你调用 run() 之前)你需要保存一个字符串引用。

    注意:您的示例,第一次调用 get() 它可以返回 null 但如果它是否运行并不重要,您是否可以根本不这样做。

    【讨论】:

    • 这个问题有点侧重于Android。 Android 中的 GC 可以通过对 Context 对象进行 GC 来回收内存,因此,如果 context 对象被硬引用,这是不可能的。这样,该对象仍然可以使用,但也可能是一个问题。所以,我的问题是,如果硬引用 Wea​​kReference.get() 结果会避免 GC 清除对象
    • @BamsBamx 一个强引用总是阻止一个对象被收集,不管你做什么。
    • 那么,在这种情况下:硬引用 Wea​​kReference.get() 结果与在 MyRunnable 构造函数中传递的硬引用“可泄漏”对象相同?
    • @BamsBamx 在这里使用弱引用而不是强引用的唯一区别是它可能会在 run() 被调用之前消失,但在它被调用时不会消失。注意:除非 GC 运行,否则没关系。
    • @BamsBamx:反复说“硬引用 Wea​​kReference.get()”似乎表明你有错误的心态。你有一个对象的强引用,仅此而已。无论您是通过调用WeakReference.get() 还是通过任何其他方式检索到该对象,都无关紧要。强引用就是强引用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-17
    • 1970-01-01
    相关资源
    最近更新 更多