我的應用程序記錄了某些對象的用法 - 我的設置使用AspectJ來識別我感興趣的上下文並記錄這些用法。我稍後加載日誌文件進行分析,但出於效率的原因,知道何時不再可訪問對象很有用。當對象被垃圾收集時記錄日誌
我目前的做法是用「垃圾記錄器」記錄我感興趣的對象,然後創建一個包含對象身份哈希碼的'保存器'對象,並將其存儲在弱哈希映射中。這個想法是當收集對象時,保存對象將從弱哈希映射中移除並收集,從而運行代碼以記錄收集對象的身份哈希代碼。我使用單獨的線程和隊列來防止在垃圾回收器中造成瓶頸。這裏的垃圾記錄代碼:
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
}
我的問題是,這似乎很令人費解,而且因爲除非需要空間弱哈希映射不一定會清除其條目,我可能會等待很長一段時間之後的對象是在錄製之前收集。基本上,我正在尋找更好的方法來實現這一目標。
注 - 我正在監視任意對象,並且無法控制其創建,因此無法覆蓋它們的最終化方法。
這聽起來像你真正想要的是[參考隊列](http://stackoverflow.com/a/14450693/869736)。 –
所以我會用ReferenceQueue替換WeakIdentityHashMap和ConcurrentLinkedQueue,但是仍然需要GarbageLogger線程來彈出收集的引用並記錄它們? – selig
這是正確的。 –