Java Garbage Collector wird alles entladen?

Meckie

Ensign
Registriert
Aug. 2005
Beiträge
254
Hi ich habe folgendes Problem ich habe ein Fenster (JFrame) auf dem liegt im center ein JPanel so und dann habe ich eine Menüleiste mit mehreren Buttons die dann jeweils ein anderes JPanel in den center laden.

so jetzt ist mir aufgefallen das mein Programm mit der Zeit wenn man ganz oft hin und her klickt immer mehr speicher frisst.
Da ich auch ein bisschen was mit Diagrammen hinzugefügt habe sieht man den anstieg des speicherverbrauchs sogar noch deutlicher.

So ich habe das so gelöst wenn man auf einen Button klickt wird alles vom JFrame entfernt und dann das neue Panel hinzugefügt. dabei speicher ich das JPanel nicht nochmal ab oder irgendwas in der Form also müsste doch eigentlich das JPanel was vorher im center des JFrames lag vom garbage collector entfernt werden, da doch keine Referenz mehr existiert

Warum steigt dann mein Speicherverbrauch ????

Ich hoffe das war einigermaßen verständlich.

MFG
Meckie
 
Naja, der Garbage Collector räumt wohl auch nicht immer unmittelbar auf würde ich sagen...
 
Heißt so viel wie: Beobachte es mal über einen längeren Zeitraum.
 
Java hat (genau wie das .NET Framework) einen nicht-deterministischen Garbage Collector. D. h. er bestimmt selbst wann er ein Objekt "aufräumt". Da du darauf keinen Einfluss nehmen kannst, musst du es so hinnehmen wie es ist.
 
ok dann lass ich es erstmal so. ist ohne hin quatsch die fenster alle 2s duchzuklicken^^
 
@TheCadillacMan: Wobei man bei .net zumindest durchaus selbst ein wenig in das Handeln des GCs eingreifen kann...
 
Also mit System.gc() kann man ihn aufrufen bringt in meinem Fall aber nix...
 
was bringt dir das nichts?

gc() heisst ja nur dass du unbenutze objekte aus dem speicher entfernst. Unbenutzt heisst... Thread t = new Thread (bla), t = .... ; t =null; eigentlich sollte nach dem t= null ein gc aufgerufen werden um den speicher zu säubern. wenn du darauf hin noch system.cg() machst wird t komplett aus dem speicher entfernt.

ich bin mir nicht sicher, aber beim erzeugen eines neuen objekts würde eventuell speicherobptimierung stattfinden, also system.gc(); Kann sein dass es in den meisten fällen aber nicht so ist.

bei deinen problem handelt sich vielleicht um eine neuallozierung des objektes. guck den code genauer an. vielleicht erzeugst du einen objekt der wundersammerweise in deinen programm nicht angezeigt wird und nicht gelöscht wird.
 
Kannst ja mal paar Destuktoren einfügen, die zeigen, wann ein Objekt wirklich zerstört wird (beispielswiese über System.out.printlin("Objekt zerstört") (nur halt Aussagekräftigere Ausgaben machen)
 
Danke das mit finalize() kannte ich garnet. Also ich hab das erstmal an einem Internalframe ausprobiert. Das räumt der direkt auf wenn ich System.gc() ausführe nachdem ich dieses geschlossen habe. Bei meinen JPanels ist das nicht derfall die scheinen die ganze Zeit zu existieren.

Ich poste mal die Methode die Aufgerufen wird und in der das erzeugte Objekt vom typ JPanel auf mein Frame kommt.

public void addPanel(JPanel p){
center.removeAll();
center.setLayout(new BorderLayout());
center.add(p, BorderLayout.CENTER);
center.validate();
center.repaint();
System.gc();
}

center ist ein JPanel und liegt im Center vom JFrame. und p ist das neu erzeuge JPanel was auf dem center landet.

Laut der beschreibung soll ja alles entfernt werden auch aus dem layout. hab sogar das layout nochmal überschrieben aber es hilft nix. ich habe irgendwie das gefühl das removeAll() einfach nicht ausreicht um ein JPanel zu zerstören.



Edit:
Ich habe jetzt auf mal die finalize Methode in mein Objekt gepackt was am meisten Speicher verbraucht, da dort viele Diagramme etc geladen werden. Wenn ich jetzt ein anderes JPanel öffnen wird das alte aufgeräumt der speicherverbrauch singt aber garnet :( ich versteh das einfach nicht. kann es vielleicht auch mit Win 7 zusammenhängen?
 
Zuletzt bearbeitet:
Naja wer den Java GC kennt wird wohl wissen, wie ihr bereits sagtet, dass er es nach eigenem ermessen steuert wann er alte objekte löscht oder nicht.

ein aufruf des gc führt aber keines wegs zu einer selbstbestimmten ausführung des gc... es ist nur ein vorschlag den der gc aber zu 89% ignorieren(ablehnen) wird =)...

also am besten gleich so programmieren das es zu so einem problem erst gar nicht kommt...
 
Warum redet ihr eigentlich alle nur von "dem" Gargabe Collector?

Sun's Java 6 hat 3 verschiedene GCs. Diese lassen sich beim Start einer Anwendung auswählen.
Mehr Infos zu diesem Thema: Garbage Collection Tuning
 
Das ist richtig. Allerdings ist Garbage Collector nicht gleich Garbage Collector.
 
Mal unabhängig vom Garbage Collector: Haben diese JPanels irgendwelche "Aufräum" Methoden alle Dispose, Finalize oder sonstiges?

Andere Möglichkeit:
Die Freigabe von Speicher durch den GC muss nicht bedeuten das der Speicher dann vom Programm an das Betriebssystem wieder zurück gegeben wird. Es kann auch sein, das das Programm weiterhin den Speicher für sich reserviert, so das es dann nicht neuen Speicher vom OS anfordert sondern sich erst aus diesem Speicher, den es bereits mal reserviert hatte, bedient. Im Taskmanager würde man dann das "Aufräumen" durch den GC nicht wirklich sehen.

Wie verhält sich dein Programm, wenn du es mal minimierst, d.h. das Fenster des Programms auf dem Desktop minimierst? Bemerkst du dann eine Veränderung an der Speichermenge (siehe Taskmanager)? Klingt komisch, aber z.B. .Net Framework schrumpft dann schon mal eine Anwendung von 120Mb auf 1MB runter...

Schau mal da rein, hilft vielleicht auch weiter: How to Handle Java Finalization's Memory-Retention Issues
 
Zuletzt bearbeitet:
Zurück
Oben