我的应用程序记录了某些对象的使用情况 - 我的设置使用 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/