java - 记录对象何时被垃圾回收

标签 java garbage-collection weakhashmap

我的应用程序记录了某些对象的使用情况 - 我的设置使用 AspectJ 来识别我感兴趣的上下文并记录这些使用情况。我稍后会加载日志文件进行分析,但出于效率原因,知道何时无法再访问对象很有用。

我目前的方法是使用“垃圾记录器”记录我感兴趣的对象,然后创建一个包含对象身份哈希码的“保存器”对象并将其存储在弱 HashMap 中。这个想法是,当对象被收集时,saver 对象将从弱 HashMap 中移除并被收集,从而运行代码来记录所收集对象的身份哈希码。我使用单独的线程和队列来防止在垃圾收集器中造成瓶颈。这是垃圾记录器代码:

public class GarbageLogger extends Thread {

    private final Map<Object,Saver> Savings = 
      Collections.synchronizedMap(new WeakIdentityHashMap<Object,Saver>());
    private final ConcurrentLinkedQueue<Integer> clearTheseHash = 
      new ConcurrentLinkedQueue<Integer>();

    public void register(Object o){
        Savings.put(o,new Saver(System.identityHashCode(o));
    }

    private class Saver{
        public Saver(int hash){ this.hash=hash;}
        private final int hash;
        @Override
        public void finalize(){
            clearTheseHash.add(hash);
        }
    }

    @Override
    public void run(){

        while(running){         
            if((clearTheseHash.peek() !=null)){
                int h = clearTheseHash.poll();
                log(h);
            }
            else sleep(100);
        }
    }

    // logging and start/end code omitted
}

我的问题是这看起来很复杂,而且因为弱 HashMap 不一定会清除它的条目,除非需要空间,我可能会在收集对象之后等待很长时间才能记录它。基本上,我正在寻找一种更好的方法来实现这一目标。

注意 - 我正在监视任意对象并且无法控制它们的创建,因此无法覆盖它们的终结方法。

最佳答案

响应垃圾回收事件的传统方式是将WeakReference注册到一个ReferenceQueue中,当被引用的对象被GC时,它们会自动入队'd,然后定期轮询 ReferenceQueue(可能在单独的线程中)以进行清理。

一个标准技巧是扩展 WeakReference 类,在清理发生时附加任何您想知道的附加信息,然后将 WeakReference 对象转换为 ReferenceQueue 返回到您的 MyWeakReference 以获取信息。

关于java - 记录对象何时被垃圾回收,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16942908/

相关文章:

java - 如何以相反的顺序迭代 LinkedList 元素?

java - 序列化 PHP => 反序列化 JAVA/Serialize for php in string format

c# - 为什么 C# 垃圾收集行为对于 Release 和 Debug 可执行文件不同?

java - 带有字符串文字和字符串对象的 weakhashmap 的行为

java - Java WeakHashMap什么时候会清理null key?

Java 语言约定; setter/getter / setter/getter

Java 执行带参数的 C 应用程序并取回返回值?

c# - .Net 与 Java 垃圾收集器

java - Java 中的 System.gc() 和 finalize() 方法有什么区别?

java - java中的内存缓存对象