kangaroody
Grünschnabel
Mir ist es vor kurzem passiert, dass ich bei einem DB-Client mit vielen großen Tabellen irgendwann ne OutOfMemoryException bekommen habe. Da ich den Fehler auf Anhieb nicht finden konnte, hab ich mir nen kleines Tool gebaut, mit dem ich beliebige Objekte darauf testen kann, ob sie auch schön brav vom garbagecollector entfernt werden.
Dachte mir, vielleicht kann es von euch ja jemand brauchen.
Aufruf sieht dann ungefähr so aus:
Meinungen/Verbesserungen/Erweiterungen sind natürlich erwünscht.
z.B. könnte man noch ne Funktion hinzufügen, mit der die registrierten Referenzen regelmäßig überprüft werden können.
Dachte mir, vielleicht kann es von euch ja jemand brauchen.
Code:
import java.lang.ref.Reference;
import java.lang.ref.WeakReference;
import java.util.Enumeration;
import java.util.Hashtable;
/**
* Testklasse mit der geprüft werden kann, ob Objekte schon vom GarbageCollector vernichtet wurden
*
*
*/
public class ReferenceTester {
private Hashtable refs = new Hashtable();
private static ReferenceTester single = null;
private ReferenceTester(){
}
/**
* Singleton
*
*/
public static ReferenceTester getTester(){
if(single==null){
single = new ReferenceTester();
}
return single;
}
/**
* registriert ein zu testendes Objekt
*
* @param id - eindeutige ID des Objekts
* @param o - zu testendes Objekt
*/
public void registerReference(String id, Object o){
Reference ref = new WeakReference(o);
refs.put(id, ref);
System.out.println("Referenz "+id+" registriert");
}
/**
* prüft ob das Objekt noch Speicher verbraucht
*
* @param id - Objekt-ID
* @return - true, wenn Objekt vom GC gekickt wurde, false falls noch nicht, bzw. nicht registriert
*/
public boolean testReference(String id){
Reference ref = (Reference) refs.get(id);
if(ref!=null){
if(ref.get()==null){
System.out.println("Referenz "+id+" wurde vom GarbageCollector vernichtet.");
return true;
} else {
System.out.println("Referenz "+id+" ist noch da");
return false;
}
} else {
System.out.println("Referenz "+id+" nicht gefunden! Falsche ID?");
return false;
}
}
/**
* Testet alle hinzugefügten Referenzen
*
*/
public void testAllReferences(){
Enumeration keys = this.refs.keys();
while(keys.hasMoreElements()){
String id = (String) keys.nextElement();
testReference(id);
}
}
}
Aufruf sieht dann ungefähr so aus:
Code:
//Dies sind sehr komplizierte Objekte mit langer Lebensdauer,
//die von vielen verschiedenen Klassen manipuliert werden
Object obby1 = new Object();
Object obby2 = new Object();
ReferenceTester tester = ReferenceTester.getTester();
tester.add("obby1_id", object);
tester.add("obby2_id", object);
...
...
...
//an einer beliebigen anderen Stelle im Programm
ReferenceTester tester = ReferenceTester.getTester();
tester.testReference("objektid");
//oder
tester.testAllReferences();
Meinungen/Verbesserungen/Erweiterungen sind natürlich erwünscht.
z.B. könnte man noch ne Funktion hinzufügen, mit der die registrierten Referenzen regelmäßig überprüft werden können.