Garbage Collector löscht anscheinend nichts

RBS2002

Aktives Mitglied
Hi,

hoffe das wurde nicht in anderen Threads behandelt - aber da ich mit OutofMemory Problemen, besonders nach Erzeugung von Listen und deren Befüllung, kämpfe hier einmal eine grundsätzliche Frage:

Ich möchte z.B. mit der folgenden Befehlsreihenfolge (kann sein das der Code so nicht funktioniert, schreibe es gerade aus den Kopf, aber das Anliegen sollte verständlich sein) die alte Referenz löschen und mit der neuen Referenz "überschreiben":

Java:
public void setListe(List neuereferenz)
{
altereferenz.clear(); //Lösche alle Einträge der Liste, zu mindestens das sollte doch Speicher frei räumen
altereferenz = null;
altereferenz = neuereferenz;
}

Nach meinem Verständniss müsste der GC nun, durch null, wissen das die Referenz nicht mehr benötigt wird und er diese löschen kann. Leider bläht sich das Programm aber nach jedem Aufruf immer weiter auf, egal ob ich die Extra-Parameter aufrufe oder nicht (mit Speicherzuweisungsparameter XS etc. läuft es natürlich länger, der Effekt bleibt aber der gleiche) - sodass man das Gefühl hat das der GC überhaupt nichts löscht.

Hier mal der grundsätzliche Ablauf des Programmes:

a) Thread (Server) wartet auf Anfragen - dieser läuft unendlich lange. Momentan kommen aber keine Clientanfragen rein womit er mit seinem Abarbeitungsserver kommuniziert und Objekte per Socket austauscht.
b) Ein zweiter Thread (Allgemeiner Abarbeitungsthread) wird gestartet. Dieser scannt, in einem neuen Thread, die Datenbanken und führt alle Abarbeitungen durch (Vergleich mit rechteliste, per E-Mail verschicken, Ergebniss an Hauptserver schicken etc.) - dieser wird, mit Hilfe von Quartz, stündlich gestartet und, wenn er fertig ist, beendet. In seinem Hauptthread kommuniziert er mit den Hauptserver.
c) In diesem zweiten Thread markiere ich alle "lokalen Referenzen" explizit. In den weiteren Abarbeitungsfunktion mache ich dies nicht (theoretisch müssten diese dort eh, mit der Entfernung der Hauptreferenz, automatisch mit markiert werden da sie ja zu diesen gehören (Vater - Kind Beziehung) - zu mindestens wenn die Funktion verlassen wird)
d) Alle Objekte werden über Locks synchronisiert. Wenn ein Thread ein Objekt anfordert wird es über einen Stream kopiert (damit er ab da an ohne Probleme damit arbeiten kann und keinen anderen thread - z.B. einen Client der die momentanen Daten abrufen will - behindert oder ein gleichzeitiger Zugriff provoziert wird), wenn es "überschrieben" wird, wird der oben genannte Algorithmus aufgerufen (die bearbeitete Kopie ersetzt in dem Fall das Original Objekt)

Ich denke mal das ich irgendwo ein Verständnissproblem zum garbage Collector habe und hoffe das mir jemand weiterhelfen kann - sollte es Verständnissprobleme bei der Beschreibung des Ablaufs geben bitte melden ;)

Vielen Dank im Voraus und mfG,
RBS2002
 

Wildcard

Top Contributor
Java:
altereferenz.clear(); //Lösche alle Einträge der Liste, zu mindestens das sollte doch Speicher frei räumen
altereferenz = null;
altereferenz = neuereferenz;
Das ist völlig sinnfrei,
Code:
altereferenz = neuereferenz
reicht völlig. Der Garbage Collector kann Objekte abräumen die nicht mehr Stark referenziert werden, nicht mehr, nicht weniger.
Um den Grund für einen Memory Leak zu finden empfehle ich die Kombination aus Heap Dumb + Eclipse Memory Analyzer Tool (MAT). Damit hat man das Problem in der Regel in wenigen Minuten identifiziert.
 

RBS2002

Aktives Mitglied
natürlich ist das sinnfrei :D Zu mindestens war es damals ein Versuch das Speicherproblem zu lösen, was - wie bisher alles - fehlgeschlagen ist. Aber danke für den Tipp ;)
 
M

Marcinek

Gast
Der GC läuft auch nur periodisch und macht das nicht instant bei jedem null oder so
 

RBS2002

Aktives Mitglied
Der GC läuft auch nur periodisch und macht das nicht instant bei jedem null oder so

Das soll er auch nicht, verbraucht ja auch Performance wenn der läuft - obwohl ich das durch die Threads eigentlich nicht merken sollte, oder?

Allerdings läuft der GC in jedem Fall bevor sich die VM mit Out Of Memory verabschiedet. Entweder du brauchst tatsächlich mehr Speicher, oder du hast einen Memory Leak, da hilft dir wie gesagt MAT weiter.

Er meldet auch mehrmals solche Out of memorys (ab und zu schafft er sogar weniger/mehr bevor der Fehler den Job beendet), aber ab einem bestimmten Punkt kommt nur noch dieser Fehler.

ja, ich werde mir das mal ansehen (muss mal versuchen das ganze in Eclipse zu importieren, gibt es so etwas auch für Netbeans) - das ich mehr Speicher benötige kann sein, nur schreibt er auch im Notfall in den Swap Bereich und füllt diesen. Zu mindestens kann man damit einmal ordentlich das System auslasten, aber das soll eigentlich nicht mein Ziel sein.

Aber, um noch einmal nachzufragen - wenn ich eine Funktion verlassen werden die darin deklarierten Referenzen automatisch dereferenziert, oder?
 

Wildcard

Top Contributor
Er meldet auch mehrmals solche Out of memorys (ab und zu schafft er sogar weniger/mehr bevor der Fehler den Job beendet), aber ab einem bestimmten Punkt kommt nur noch dieser Fehler.
Die VM steigt mit Out Of Memory aus wenn der GC mehr als 90% der Rechenzeit verbrät und dabei kaum Speicher freigeben kann.

ja, ich werde mir das mal ansehen (muss mal versuchen das ganze in Eclipse zu importieren, gibt es so etwas auch für Netbeans)
Du brauchst nichts in Eclipse zu 'importieren' ausser dem Heap Dump.
das ich mehr Speicher benötige kann sein, nur schreibt er auch im Notfall in den Swap Bereich und füllt diesen.
Swapping erledigt das OS und das hat nichts damit zu tun. Der maximale Heap den die VM allokieren kann wird mit -Xmx geregelt, unabängig davon ob Teile davon geswapped werden.

Aber, um noch einmal nachzufragen - wenn ich eine Funktion verlassen werden die darin deklarierten Referenzen automatisch dereferenziert, oder?
Referenzen selbst sind nicht dein Problem, es geht um die Objekte. Die können wie gesagt erst dann abgeräumt werden wenn keine starke Referenz mehr auf sie zeigt. Die 'schwachen' Referenzen Weak, Soft und Phantom Referenz verhalten sich etwas anders, aber du würdest wissen wenn du mit etwas anderem als starken Referenzen arbeitest.
Und ja, wenn du eine Variable innerhalb einer Methode deklarierst und diese Variable etwas referenzieren lässt, dann 'erlischt' die Referenz sobald die Methode verlassen wird, darüber musst du dir keine Sorgen machen und du musst auch nicht irgendetwas 'null' setzen.
Anders sieht die Sache natürlich bei Membern und statischen Variablen aus.
 

RBS2002

Aktives Mitglied
danke, wird der Heap Dump nicht als Parameter gestartet? (Zu mindestens wird es hier so beschrieben Link) Oder meinst du etwas anderes? Das Eclipse Tool wird man ja sicherlich als Plugin laden können, oder?
 

Wildcard

Top Contributor
Als Plugin oder Standalone Anwendung. Heap dumps kann man auf verschiedene Weisen erstellen.
-programmatisch
-in intervallen
-per externer Applikation (Visual VM zB)

Am einfachsten dürfte es sein -XX:+HeapDumpOnOutOfMemoryError als Startup Parameter zu übergeben. Dann erstellt die JVM den Dump sobald der OutOfMemoryError fliegt.
 

Marco13

Top Contributor
Die VisualVM ist für sowas IMHO am praktischsten (wenn man nicht den TPTP installieren oder sogar Geld ausgeben will). Etwas versteckt im JDK\bin\ Verzeichnis, "jvisualvm.exe" starten....
 

RBS2002

Aktives Mitglied
Ich habe, da ich noch auf den Dump warte (das Programm läuft schon 3-4 Tage bis der Fehler kommt) nochmal zwei kleine Fragen ;)

a) Die Maschine auf der das Programm läuft hat momentan 1024MB Ram,davon werden vom System und den anderen laufenden Programmen ca.130MB belegt. Mein Programm läuft derzeit mit dem Parameter:

Code:
java -jar -Xms256m -Xmx900m -XX:MaxPermSize=256M -XX:MaxNewSize=128M -XX:+UseParallelGC Server.jar

Steckt da schon der Fehler im Detail und kann man noch etwas verbessern? Wie gesagt,der Speicher läuft - wenn das Programm entsprechend lange läuft - zu 100% voll, danach lagert er alles logischerweise in den Swap aus (das Programm lief früher unter einer Debian Kiste mit 2GB Ram, dort hat er aber ständig nur "Killed" geliefert und das Progamm selbstständig geschlossen, die neue ist da doch auskunftsfreudiger). Nicht das ich mit meinen Parametern den GC verhindere :D

b) Weiß jemand wo ich dieses Programm unter Linux finden müsste oder ob es einen Befehl gibt um das rauszubekommen?
 
Zuletzt bearbeitet:
T

tuxedo

Gast
Wenn der TO mit Netbeans arbeitet: Da gibts doch schon nen recht guten Profiler? Wozu der Umweg über MAT und Eclipse?

--> Google -> "Netbeans Profiler"
 

RBS2002

Aktives Mitglied
also ich habe mir jetzt mal mit VisualVM mein HeapDump angesehen (es ist ca. 900MB groß, kann es deshalb nicht hochladen). Kann besonders viel Speicher nehmen char[] und String Variablen ein. String ist ja vielleicht noch okay, aber char[] benutze ich, zu mindestens nicht absichtlich, eigentlich nicht. Jetzt mecket er, soweit ich das überblicken kann, immer über den ObjectOutputStream vom Socket - soweit ich mich belesen habe müsste ich diesen schließen um die Ressourcen wieder frei zu bekommen - aber dann würde ich ja die Verbindung bzw. den Stream verlieren... Oder gibt es da noch eine andere Möglichkeit. Momentan sieht mein Writer Objekt so aus:

Java:
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package Server_Client;

import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 *
 * @author RBS2002
 */
public class Write{
    
    private ObjectOutputStream output;
    private Lock writer = new ReentrantLock();

    public Write(ObjectOutputStream output) {
        this.output = output;
    }

    public void write(Object object){
            writer.lock();
            try{
            output.writeObject(object);
        } catch (IOException ex) {
        }finally{
            writer.unlock();
        }
    }

    public void close(){
        try{
            output.close();
        }catch(Exception ex){}
    }
}

Wie gesagt, die Verbindung muss ständig laufen da es kein Client sondern die Verbindung zum Datenserver ist. Hoffe das wird jetzt nicht zu sehr Off-Topic - aber vielleicht ist es gerade die Lösung zu meinem Problem, zu mindestens wenn ich den Viewer und das Dump richtig lese :D

MfG RBS2002
 
Zuletzt bearbeitet:

Wildcard

Top Contributor
Hast du MAT ausprobiert? Der gibt dir wie gesagt einen Report der Leak Suspects.
Zum Object Output Stream: Der ObjectOutputStream cached alle Objekte die darüber serialisiert werden. Um den Cache zu leeren kann man wahlweise close oder reset aufrufen.
 

RBS2002

Aktives Mitglied
Ist leider bis jetzt ein bisschen schwierig gewesen da es Eclipse und meine persönlichen Rechner bisher nicht geschafft haben irgendwelche Sockets aufzubauen und ich es dadurch nicht zum laufen kriege. Ich werde mir den HeapDump noch einmal morgen genauer ansehen. Das Tool was ich verwendet habe war schon dahingehend sehr hilfreich, zumal es auch gezeigt hat das die ganzen LinkedListen die ich zuerst in Verdacht hatte einen sehr kleinen Teil des Speichers ausgemacht haben. Bisher läuft das Programm, da es sowieso noch keinen brauchbaren Client gibt, ohne den Objektversand zum Hauptserver. Aber das mit den Cachen hört sich soweit ganz interessant an, währe in meinem Fall (ich will die Verbindung nicht verlieren) das

Java:
public void write(Object object, Socket socket){
            writer.lock();
            try{
            output = new ObjectOutputStream(socket.getOutputStream());
            output.writeObject(object);
        } catch (IOException ex) {
        }finally{
            output.close();
            writer.unlock();
        }
    }

oder das besser:

Java:
public void write(Object object){
            writer.lock();
            try{
            output.writeObject(object);
        } catch (IOException ex) {
        }finally{
            writer.unlock();
           output.reset();
        }
    }

(Ich schätze mal das zweite - wenn ich jetzt von meinem Verständnis ausgehe hat der Socket ja nur einen OutputStream - und wenn ich den schließe dürfte ja der Stream und damit im Prinzip auch der Socket hinüber sein - oder wird durch die Übergabe ein neuer Stream erstellt der diesen Stream nur nutzt, die Daten bei sich cachet und der eigentliche Stream, also der Stream vom Socket, nichts davon mitbekommt und auch nach der Schließung des ObjectOutputStreams noch weiterläuft), aber vielleicht mache ich da grundsätzliche Fehler)
 
Zuletzt bearbeitet:
Ähnliche Java Themen
  Titel Forum Antworten Datum
J Garbage collector Allgemeine Java-Themen 3
D Garbage Collector Allgemeine Java-Themen 3
A Garbage Collector Allgemeine Java-Themen 3
A Garbage Collector in NetBeans vs. exe Anwendung Allgemeine Java-Themen 33
L Garbage Collector lässt Programm kurz hängen Allgemeine Java-Themen 10
H2SO3- SCJP garbage collector frage Allgemeine Java-Themen 13
S Garbage Collector entlasten Allgemeine Java-Themen 2
JStickman Der Garbage Collector Allgemeine Java-Themen 13
P Threads ohne Referenz & der Garbage Collector Allgemeine Java-Themen 2
S garbage collector prog Allgemeine Java-Themen 4
S Threads <-> Garbage Collector Allgemeine Java-Themen 2
M Java Garbage Collector Frage (Singleton Pattern) Allgemeine Java-Themen 13
P Garbage Collector funktioniert nicht richtig? Allgemeine Java-Themen 12
M Problem mit garbage collector Allgemeine Java-Themen 19
R Garbage Collector rennt die ganze Zeit Allgemeine Java-Themen 7
M Garbage Collector Allgemeine Java-Themen 5
T Garbage Collection Frage Allgemeine Java-Themen 15
B Garbage Collection Logfile: Binary File Allgemeine Java-Themen 2
hdi Garbage Collection Allgemeine Java-Themen 12
T Objekt der Garbage Collection zugaenglich machen? Allgemeine Java-Themen 7
F Frage zu Memory Leak, Garbage Collection und Profiler-Tools Allgemeine Java-Themen 6
M Wie lange dauert ein garbage collection Allgemeine Java-Themen 7
R Garbage Collection bei gegenseitiger Objektreferenz Allgemeine Java-Themen 2
M Garbage manuell loswerden Allgemeine Java-Themen 29
M garbage collection Allgemeine Java-Themen 14
G Frage zur Garbage Collection Allgemeine Java-Themen 5
H Collector Generics Problem (incl. Stream & Lambda) Allgemeine Java-Themen 4
P Grabage Collector Allgemeine Java-Themen 8
N lwjgl Projection Matrix löscht Dreieck Allgemeine Java-Themen 1
L Excel Datei löscht sich selbst im Programm - Java Allgemeine Java-Themen 3
Meeresgott Input/Output OutputStream löscht Datei Allgemeine Java-Themen 7
E Liste löscht sich selbstständig Allgemeine Java-Themen 5
H File delete löscht manche dateien nicht Allgemeine Java-Themen 2
B log4j löscht meine Logdateien Allgemeine Java-Themen 2

Ähnliche Java Themen

Neue Themen


Oben