【问题标题】:Java: Looking for mutable/re-referenceable weak reference implementationJava:寻找可变/可重引用的弱引用实现
【发布时间】:2011-02-13 21:53:00
【问题描述】:

我正在寻找类似于java.lang.ref.WeakReference 的弱引用实现,但它提供了set() 方法或其他重新引用创建的弱引用对象的方式。示例如下:

MutableWeakReference ref = new MutableWeakReference(someObject);
ref.set(anotherObject);

我需要这个来避免创建对象,在我的情况下,这会使执行时间减慢一个数量级,因为我不断地更改我的弱引用所引用的对象。

我试图从 JDK 复制代码,但似乎不可能,因为 java.lang.ref.Reference 使用内部的 sun.misc.Cleaner 类。我还查看了 Android 实现,但它似乎依赖于 Dalvik VM 进行垃圾收集。我想知道这是否真的可以在不改变 JVM / 环境的情况下实现。

【问题讨论】:

  • 如果您经常更改参考,是否可以暂时保留它,如果它老化了再获得一个新的WeakReference
  • 如果 WeakReference 的所指对象是可变的,则可能会出现竞争条件,即您在将 Reference 放入 ReferenceQueue 后对其进行变异。我不认为这是要走的路。

标签: java implementation mutable weak-references


【解决方案1】:

难道不能把你的引用封装成一个简单的

class MyOwnReference<T> {
    public T ref;
    public void set(T o) { ref = o; }
}

并创建WeakReference&lt;MyOwnReference&lt;WhatEver&gt;&gt;?

我想知道这是否真的可以在不改变 JVM/环境的情况下实现。

不,您可能无法“重新实现”WeakReference。它是一个 JVM 支持的类。

您确定是 WeakReference 实例的创建减慢了速度吗?我不认为这样做

ref = new WeakReference(someObject);

而不是一些

ref.set(anotherObject);

会贵很多。

【讨论】:

  • 我实际上是在实现某种迭代器。每当我前进到下一个条目时,我都需要创建一个新的 WeakReference。我已经进行了一些测试,这似乎慢了 8-10 倍。
  • 我认为这个解决方案没有帮助。我刚刚运行了一个简单的基准测试来比较创建强引用和弱引用。结果强烈支持弱引用。这很奇怪,但可重现,很可能是由 GC 开销和强引用占用的不可回收内存造成的巨大开销引起的。
【解决方案2】:

我实际上是在实现某种迭代器。每当我前进到下一个条目时,我都需要创建一个新的WeakReference

我很困惑为什么你需要在迭代器中使用WeakReferenceWeakReference 的正常用例是对对象的长期引用。但是迭代器通常是短期对象,而迭代通常是短期过程。它/它们在短期内使用对目标对象的普通(强)引用这一事实不应该是一个问题。

我已经运行了一些测试,这似乎慢了 8-10 倍。

同样,这表明您根本不应该使用 WeakReference

是否有特定原因导致常规参考对您不起作用?

【讨论】:

  • 我想实现一个非失败快速迭代器,一旦它引用的条目被删除,它就会失效。 WeakReference 提供了部分安全性,即如果该条目被删除,则无法“取消引用”已删除的迭代器(安全性只是部分的,因为不能保证对象会立即被删除)。
  • 您几乎可以肯定,它不会立即被删除。而且,它可以从其他地方引用,并且根本不会被删除。我看不出这样的迭代器应该提供什么优势。快速失败有时很好,非失败(例如,反映集合的某些旧状态)有时很好,我真的不知道你的版本。
  • @leden - 我可以想到更好(更便宜,更可靠)的实现方式......取决于您正在迭代的确切内容。如果您提供了您正在迭代的数据结构的更多详细信息,我可能会更具体。
  • 我正在迭代的东西最接近链表。到目前为止,我提出的最好方法是为每个条目添加一个额外的布尔条目。所以迭代器可以检查条目是否被删除。这是一个轻微的内存开销,如果存在那些可变的弱引用,就会存在。你有更好的选择吗?
【解决方案3】:

您不能自己编写弱引用。这是 JVM 专门处理的“特殊”类。

只需使用新的弱引用

class MutableWeakReference<T> 

    WeakReference<T> wr;

    void set(T obj)
        wr = new WeakReference(obj);  

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-11-08
    • 2018-04-17
    • 2011-03-11
    • 2021-08-10
    • 1970-01-01
    • 1970-01-01
    • 2019-07-18
    • 1970-01-01
    相关资源
    最近更新 更多