【问题标题】:Number of references to the Java object对 Java 对象的引用数
【发布时间】:2014-12-25 19:31:27
【问题描述】:

有没有办法检查对 Java 对象的引用数量?

让 myObject 成为一个对象的引用,并且该对象已经完成了它的工作。我准备让它在处理方法中死掉,并将引用 myObject 用于其他目的,所以欢迎垃圾收集器杀死它。但我不确定是否没有其他对该对象的引用。如何检查?

【问题讨论】:

  • 为什么重要?您不需要显式地 null 您的实例,当它们不可访问时,它们符合被垃圾收集(何时或是否它们将被垃圾收集未指定)。跨度>
  • 假设我要将 myObject 用于其他目的。我稍微改述一个问题。
  • 没有。我还是不太明白,你在找WeakReference吗?
  • 拥有 GC 的全部意义在于您不会必须跟踪对对象的引用数。如果你喜欢这种记账方式 - 最好转向 c++ ...

标签: java object garbage-collection


【解决方案1】:

正如 cmets 中所述,您几乎可以肯定不想/不需要知道对对象的引用数量。垃圾回收的优点是程序的一部分可以将其对对象的引用清空,而无需关心程序的另一部分是否仍然持有对该对象的引用。

如果你想知道一个对象何时被垃圾回收,那么就像 Elliott Frisch 在 cmets 中所说的那样,给它一个 WeakReference - 如果 reference.get() 返回 null 则该对象已被垃圾回收。更粗略的替代方法是覆盖对象的 finalize 方法并在调用时记录。

如果您认为自己有内存泄漏,请使用Eclipse memory analyzer 或其他一些内存分析/分析工具。

如果你真的需要知道一个对象的引用数量,那么我能想到的唯一解决方案是使用Jikes RVM - 它有一个内存管理工具包,其中包括引用计数收集器和备份周期收集,你应该能够挂钩到收集器以确定对对象持有的引用数量(在运行备份周期收集器之后,除非您确定对象不持有对自身的传递引用)。使用 RVM 并非易事。此外,您不应该在生产环境中使用 RVM - 它严格来说是一种研究工具。

您也可以尝试将以下内容组合在一起

public class Wrapper<T> {
  private WeakReference<T> thisReference;
  private ConcurrentLinkedQueue<WeakReference<Object>> references = 
    new ConcurrentLinkedQueue<>();

  public T getObject(Object obj) {
    T thisObject = thisReference.get();
    if(thisObject != null) {
      references.offer(new WeakReference(obj));
    }
    return thisObject;
  }

  public int referenceCount() {
    if(thisReference.get() == null) {
      references.clear();
      return 0;
    } else {
      Iterator<WeakReference<Object>> iterator = references.iterator();
      while(iterator.hasNext()) {
        WeakReference<Object> reference = iterator.next();
        if(reference.get() == null) {
          iterator.remove(); 
        }
      }
      return references.size();
    }
  }
}

这个想法是强制对象通过getObject获取对该对象的引用,这会将WeakReference注册到获取对象。然后referenceCount 将计算这些非空的WeakReferences 的数量。这更简单但不如通过 Jikes 使用真正的引用计数收集器准确,因为在 references 集合中可能存在不可访问的 WeakReferences 尚未被垃圾收集,因此是非空的;也没有什么可以阻止转义的thisObject 传递给另一个不会通过getObject 注册的对象。这也引入了谁持有对Wrapper 的引用的新问题,所以我不确定这是否会给你带来任何好处。底线是准确的引用计数需要在虚拟机(即 Jikes)级别完成,而不是用户代码。

【讨论】:

    猜你喜欢
    • 2015-02-05
    • 2013-05-15
    • 1970-01-01
    • 2011-06-05
    • 1970-01-01
    • 2020-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多