Meine Anwendung protokolliert die Verwendung bestimmter Objekte - mein Setup verwendet AspectJ, um die Kontexte zu identifizieren, die mich interessieren, und protokolliert diese Verwendungen. Ich lade später die Protokolldateien zur Analyse, aber aus Effizienzgründen ist es nützlich zu wissen, wann ein Objekt nicht mehr erreichbar ist.Protokollierung, wenn Objekte Müll gesammelt werden
Mein aktueller Ansatz besteht darin, die Objekte, an denen ich interessiert bin, mit einem 'Mülllogger' zu protokollieren, der dann ein 'Sicherheitsobjekt' erstellt, das den Identitätshashcode des Objekts enthält und in einer schwachen Hash-Map speichert. Die Idee ist, dass, wenn das Objekt gesammelt wird, das Sicherungsobjekt aus der schwachen Hash-Map entfernt und gesammelt wird, wodurch Code ausgeführt wird, um den Identitäts-Hash-Code des gesammelten Objekts zu protokollieren. Ich verwende einen separaten Thread und eine Warteschlange, um einen Flaschenhals im Garbage Collector zu vermeiden. Hier ist der Müll-Logger-Code:
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
}
Mein Problem ist, dass dies scheint sehr verworren und, weil schwache Hash-Karte wird nicht unbedingt die Einträge löschen, es sei denn Platz benötigt wird, könnte ich eine lange Zeit warten, nachdem das Objekt vor der Aufnahme gesammelt. Im Grunde suche ich nach einem besseren Weg, dies zu erreichen.
Hinweis - Ich überwache willkürliche Objekte und habe keine Kontrolle über ihre Erstellung, so dass sie ihre Finalisierungsmethoden nicht überschreiben können.
Es klingt wie, was Sie wirklich wollen, ist eine [Reference Queue] (http:// Stackoverflow.com/a/14450693/869736). –
Also würde ich die WeakIdentityHashMap und ConcurrentLinkedQueue durch eine ReferenceQueue ersetzen, aber würde immer noch den GarbageLogger-Thread benötigen, um gesammelte Referenzen zu veröffentlichen und sie zu protokollieren? – selig
Das ist richtig. –