记录对象是否被垃圾回收

sel*_*lig 5 java garbage-collection weakhashmap

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

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

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
}
Run Code Online (Sandbox Code Playgroud)

我的问题是,这似乎非常复杂,因为弱哈希映射不一定会清除它的条目,除非需要空间,我可能会在收集对象之前等待很长时间才能记录它.基本上,我正在寻找一种更好的方法来实现这一目标.

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

Lou*_*man 6

响应垃圾收集事件的传统方法是WeakReference使用a 注册s,ReferenceQueue当引用的对象是GC时,它们将自动排队,然后定期轮询ReferenceQueue(可能在单独的线程中)进行清理.

标准技巧是扩展WeakReference类,在清理发生时附加您想要了解的任何其他信息,然后WeakReferenceReferenceQueue后面的对象强制转换MyWeakReference为获取信息.