对Java对象的引用数

时间:2014-12-25 19:31:28

标签: java object garbage-collection

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

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

1 个答案:

答案 0 :(得分:0)

正如评论中所述,您几乎肯定不希望/需要知道对象的引用数量。垃圾收集的优点是程序的一部分可以使其对对象的引用无效,而无需关心程序的另一部分是否仍保留对该对象的引用。

如果你想知道一个对象何时被垃圾收集,那么按照Elliott Frisch在评论中所说的那样拿一个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获取对象的引用,WeakReferencereferenceCount注册到获取对象。然后,WeakReferences将计算非空的WeakReferences个数。这比通过Jikes使用真正的引用计数收集器更简单但不准确,因为references集合中可能存在不可访问的thisObject尚未被垃圾收集并且是因此非空;还有一点也没有阻止转义的getObject被传递给另一个未通过Wrapper注册的对象。这也引入了谁将{{1}}引用的新问题,因此我不确定这是否会为您带来任何好处。最重要的是,准确的引用计数需要在虚拟机级别(即Jikes)完成,而不是用户代码。