G
Guest
Gast
Hi,
kennt jemand die Lösung für folgendes Problem:
1) Es liegt eine Liste (ArrayList) mit WeakReference(n) vor, die auf eine
Reihe von Listener-Objekten verweisen.
Es sind u.a. auch JInternalFrame, die das ListenerInterface implementieren.
Grundsätzlich gibt es zwei Typen dieser Listener.
a) direkt in den Frames implementiert
class Whatever extends JInternalFrame implements MyListener
{
...
}
b) als Adapter mit Delegation an das Frame
class Whatever extends JInternalFrame
{
MyListener listener = new MyAdapter();
...
}
2) Wird ein Fenster geschlossen/entfernt (DISPOSE_ON_CLOSE), dauert es
immer viel zu lange, bis sie vom GC als "weakly reachable" markiert werden.
3) Expliziter Aufruf von System.gc() führt auch nicht dazu, dass die
WeakReference-Instanzen "null" bei der Methode get() zurückgeben.
Klartext: Es existieren keine "harten" Referenzen mehr, die auf die Listener
Objekte verweisen. (auch nicht in JDesktopPane oder sonstwo)
4) Erst nach einer gewissen Zeit (>1 Minute), sind die Listener wirklich
weg bzw. WeakReference.get() gibt erst dann null zurück.
Folgender Codeausschnitt zeigt, wie es funktionieren sollte:
Das Problem sind die "Listener-Leichen", die in einem undefinierten
Zustand sind. Es kommt zu unvorhersehbaren Fehlern, wenn man
Events an diese Listener schickt.
Eine Idee was die Ursache sein kann?
Gruß,
Michael
kennt jemand die Lösung für folgendes Problem:
1) Es liegt eine Liste (ArrayList) mit WeakReference(n) vor, die auf eine
Reihe von Listener-Objekten verweisen.
Es sind u.a. auch JInternalFrame, die das ListenerInterface implementieren.
Grundsätzlich gibt es zwei Typen dieser Listener.
a) direkt in den Frames implementiert
class Whatever extends JInternalFrame implements MyListener
{
...
}
b) als Adapter mit Delegation an das Frame
class Whatever extends JInternalFrame
{
MyListener listener = new MyAdapter();
...
}
2) Wird ein Fenster geschlossen/entfernt (DISPOSE_ON_CLOSE), dauert es
immer viel zu lange, bis sie vom GC als "weakly reachable" markiert werden.
3) Expliziter Aufruf von System.gc() führt auch nicht dazu, dass die
WeakReference-Instanzen "null" bei der Methode get() zurückgeben.
Klartext: Es existieren keine "harten" Referenzen mehr, die auf die Listener
Objekte verweisen. (auch nicht in JDesktopPane oder sonstwo)
4) Erst nach einer gewissen Zeit (>1 Minute), sind die Listener wirklich
weg bzw. WeakReference.get() gibt erst dann null zurück.
Folgender Codeausschnitt zeigt, wie es funktionieren sollte:
Code:
// Queue, in die nicht mehr "gültige" WeakReferenzen kommen
ReferenceQueue refQueue = new ReferenceQueue();
// Eine Referenz für den Test
Integer intField = new Integer(1);
// Und das dazugehörige WeakReference
WeakReference ref = new WeakReference(intField, refQueue);
// Die Referenz ist noch gülig, daher ist die Ausgabe "false" OK
System.out.println("ref.get()==null : "+ (ref.get()==null));
// Die Referenz wird entfernt und GC aufgelöst
intField = null;
System.gc();
// Hier ist die Referenz nicht mehr gültig; "true" ist also OK
System.out.println("ref.get()==null : "+ (ref.get()==null));
WeakReference tmpRef;
// Wenn das nicht mehr referenzierte Objekt in die Queue gesetzt wurde
if((tmpRef = (WeakReference)refQueue.poll()) != null)
{
// Alles OK, das Ding ist endgültig weg
System.out.println("ref enqueued : " + (tmpRef.get()==null));
}
else
{
// Wurde nicht freigegeben.
System.out.println("ref NOT enqueued");
}
Das Problem sind die "Listener-Leichen", die in einem undefinierten
Zustand sind. Es kommt zu unvorhersehbaren Fehlern, wenn man
Events an diese Listener schickt.
Eine Idee was die Ursache sein kann?
Gruß,
Michael