Objekt loeschen



  • Wie kann ich in Java ein Objekt dem Garbage Collector uebergeben. Also ihn quasi gezielt anweisen ein Objekt zu loeschen?

    Oder allg. ein Objekt (zB was eine Variable in einer andern Klasse ist, die dieses aber nun nicht mehr braucht) wegschmeissen?



  • Eigentlich besteht da gar kein Bedarf. Das wird vom gc alles automatisch erledigt sobald ein Objekt nicht mehr referenziert wird. Aber wenn du darauf bestehst:

    //Referenzen auf Objekt sollten hier gleich null sein
    System.gc();
    


  • Das ist allerdings kein Garant. Auch wenn das Objekt null ist muss der GC durch diesen Aufruf noch lange nicht den Speicher freigeben.



  • Corcovado schrieb:

    Wie kann ich in Java ein Objekt dem Garbage Collector uebergeben. Also ihn quasi gezielt anweisen ein Objekt zu loeschen?

    Oder allg. ein Objekt (zB was eine Variable in einer andern Klasse ist, die dieses aber nun nicht mehr braucht) wegschmeissen?

    Was versprichst du dir davon? Wenn du die Möglichkeit hättest, Objekte manuell zu entfernen, würdest du damit den GC sehr viel ineffizienter machen.



  • CengizS schrieb:

    Das ist allerdings kein Garant. Auch wenn das Objekt null ist muss der GC durch diesen Aufruf noch lange nicht den Speicher freigeben.

    Stimmt schon, aber über kurz oder lang wird es vom gc freigegeben.



  • Joar über kurz oder lang wird auch ohne System.gc der Speicher wieder freigegeben 🙂



  • spätestens wenn Win wieder mal abkratzt. 😃



  • spätestens wenn Win wieder mal abkratzt.

    das loesche ich dann lieber doch selber, da's bei mir auf Debian laeuft, 😃

    Was versprichst du dir davon?

    Tja, ich habe ein Program geschrieben, welches aus einer Datei sehr viele Werte einliest, mit diesen nen Haufen Berechnungen macht und dann wieder speichert. Da es eigentlich mein erstes groesseres Projekt darstellt stehe ich nun, gegen Ende vor vielen Fragen, die (wahrscheinlich auf Grund schlechter Implementation LOL) auftretenden Performance Bremsen rauszuhauen. Im Rahmen dieses Unternehmens hab ich nun festgestellt, dass zB geladen wird, die Berechnung durchgefuert wird, wieder gespeichert wird und danach mein ganzes System sehr abgebremst wird.
    Nachdem ich ueberlegt hab (ich bin grad erst dabei Jrat als Profiler zu nutzen, da les ich mich aber auch grad erst rein), kam ich drauf dass das Objekt, welches die Berechnungen durchfuehrt (plus alle anderen dazu benoetigten Objekte) nach der Berechnung ja natuerlich nicht einfach geloescht werden, da das Objekt, bzw der Zeiger darauf eine Klassenvariable einer Facadenklasse der grafischen Oberflaeche darstellt.
    Was ich momentan mache ist einfach, nach der Berechnung dieses Objekt welches die Berechnungen durchfuehrt einfach neu zu initialisieren - wodurch ja der ganze alte Kram auch einfach geloescht wird. Ich erkenne hier natuerlich auch die Vorteile lokaler ggnueber globaler Konzepte, dies is allerdings bei meinem (wohl doch noch etwas verunstaltetem Code 😉 nicht immer moeglich) ...und aus diesem Grund suche ich den Weg den gc vllt direkt anzuweisen Objekte zu loeschen. Vielleicht isses ja in meinem Fall auch einfach besser, die Objekte nur einfach neu zu initalisieren?!



  • Hi

    das mit der neu initallisierung scheint mir in deinem fall auch der sinvollere weg. vorallem werden dadurch nicht alle deine objekte aus dem speicher gelöscht und wieder angelegt. was ja zeit braucht.

    auserdem ist mir zumindestens nicht bekannt wie man dem gc sagen kann das er ein bestimmtes objekt löschen soll. Ich hab den gc eher als 3 jähriges bockiges kind in errinnerung, dem man zwar was sagen kann, nur ob er es auch macht, und vorallem wann, das weis man nie.

    gruss



  • da das Objekt, bzw der Zeiger darauf eine Klassenvariable einer Facadenklasse der grafischen Oberflaeche darstellt.

    ich würd dir sehr empfehlen diese klasse auf zu trennen in 2 klassen, eine die die berechnungen durchführt und eine die die daten an die GUI übergibt.
    am besten ist es eh für jede aufgabe eine eigene klasse anzulegen und nicht eine klasse alles übernehmen zu lassen. auf den ersten blick ist es vieleicht bequemer aber dann wird es fürchterlich ineffizient und unübersichtlich.



  • Befasst euch mal damit, wie der GC arbeitet. Er löscht gar nichts aus dem Speicher. Er arbeitet nicht auf toten Objekten. Das geht auch gar nicht. Und deshalb kann man ein Objekt auch nicht von Hand löschen. Das zu ermöglichen würde den GC sau ineffizient machen, also ist es nicht gemacht worden.

    Und wenn du den GC verdächtigst, die Performance-Bremse zu sein, dann solltest du dir dafür doppelt gute Beweise zulegen, denn das ist selten der Fall. Für wahrscheinlicher halte ich es, dass deine "Berechnungen" (die du nicht näher ausgeführt hast) optimierungsbedürftig sind. Der GC kommt sehr gut mit vielen kurzlebigen Objekten gleichzeitig klar, Allokieren geht auch sauschnell und gelöscht werden die Objekte gar nicht erst (also keine Arbeit).
    Das einzige, was dem GC echt Arbeit macht, sind Objekte, die mittel-lang leben. Die langlebigen werden irgendwann nicht mehr bewegt, die kurzlebigen gar nicht. Die mittel-lang lebenden werden aber einmal bewegt und sind dann erst tot. Das ist ungünstig, wenn es viele davon gibt.



  • Und never ever call System.GC(), außer du weißt ganz genau, was du da tust. Es gibt kaum eine bessere Möglichkeit, den GC lahm zu machen, als ihn von Hand aufzurufen.



  • OK
    das war aufschlussreich.
    Ich habe die Klasse natuerlich aufgeteilt, mit "Facade" meinte ich eigentlich auch nur die Klasse die die Daten im Hintergrund (5 Klassen) den Daten im Vordergrund uebergibt.

    Und wenn du den GC verdächtigst, die Performance-Bremse zu sein, dann solltest du dir dafür doppelt gute Beweise zulegen, denn das ist selten der Fall.

    Naja, wie eben gesagt, mein Program ist sicherlich im allgemeinen optimierungsbeduerftig, daran arbeite ich ja gerade.
    Aber - Mein Programm lief vorher so ab:
    Daten lesen in Objekte, berechnen (nur +-*/), Daten der Objekte speichern - fertig.

    Danach, war das ganze System lahm. Nun mache ich danach einfach ein Objekt ist neues Objekt, wodurch das alte doch automatisch geloescht wird und nun hab ich das Problem nicht mehr. Woran solls denn dann bitte gelegen haben???

    Ich denke zwar, dass das nix direkt mit dem GC zu tun hat, allerdings interessierte mich ja eben ob es noch andere Moeglichkeiten gibt Objekte (wie in meinem Beispiel) frei zugeben zum verschrotten und ob meine Methode (mit neuem ueberschreiben) eigentlich sinnvoll ist.



  • Danach, war das ganze System lahm. Nun mache ich danach einfach ein Objekt ist neues Objekt, wodurch das alte doch automatisch geloescht wird und nun hab ich das Problem nicht mehr. Woran solls denn dann bitte gelegen haben???

    Ich bin mir nicht sicher, ob ich dich richtig verstanden habe. Wann geht es schneller, wenn du alte Objekte recyclest, ihnen also einen neuen Wert gibst? Das kann natürlich nicht ausgeschlossen werden, falls ich das jetzt richtig verstanden habe.
    Was genau meinst mit "das alte löschen" ?



  • also ich lese alle Daten in ein Objekt (abgeleitet von ArrayList) ein, dazu hab ich noch einige Funktionen in die abgeleitete Klasse implementiert (addieren der Werte usw).

    Nachdem die Arbeit mit diesem Objekt fertig ist und dessen Daten wieder gespeichert sind (das Objekt also ueberfluessig waere) hab ich noch immer eine Variable die darauf verweist - soz. einen Zeiger darauf (weiss nich ob die Bezeichnung in Java hier richtig ist).

    Diesem Zeiger weise ich nun eben nach abgeschlossener Berechnung einfach eine neue Instanz seiner Klasse zu. Ich dachte es gebe vielleicht auch eine Moeglichkeit nur das Objekt zu loeschen, da mir meine Vorgehensweise etwas umstaendlich erschien.



  • Wenn du die neue Instanz nur erstellst, um die Referenz auf das alte Objekt aufzuhebenm dann kannst du doch die Referenz einfach auf null setzen. 😕
    Dadurch wird zwar das Objekt nicht notwendigerweise sofort gelöscht, aber es kann in bestimmten Fällen dem GC die Arbeit natürlich erleichtern.



  • Optimizer schrieb:

    Dadurch wird zwar das Objekt nicht notwendigerweise sofort gelöscht, aber es kann in bestimmten Fällen dem GC die Arbeit natürlich erleichtern.

    Vorallem _darf_ er es dann löschen.

    Solange du das Objekt zwar nicht brauchst, aber immer noch eine Referenz darauf hältst, darf der GC logischerweise das Objekt nicht löschen. Ob du der Referenz null zuweist oder sie Out-Of-Scope gehen lässt, ist aber egal.

    Diese unnötigen Objekte die man nicht mehr braucht aber noch referenziert, können die Performance stark beeinflussen. Denn sie belegen sinnlos Speicher. Mit einem GC werden einem solche Situationen erschwert (weil man eben wirklich eine konkrete Referenz auf das 'tote' Objekt haben muss) aber sie ganz zu verhindern ist leider nicht möglich.



  • Diese unnötigen Objekte die man nicht mehr braucht aber noch referenziert, können die Performance stark beeinflussen. Denn sie belegen sinnlos Speicher. Mit einem GC werden einem solche Situationen erschwert (weil man eben wirklich eine konkrete Referenz auf das 'tote' Objekt haben muss) aber sie ganz zu verhindern ist leider nicht möglich.

    Genau das ist mein Problem gewesen. Ich weiss das man denn gc nicht zwingen kann zu arbeiten (zumindest jetzt weiss ich es). Aber wenigstens selber soweit die Daten bereinigt zu haben, damit der gc sich drauf stuertzen kann war das was ich nun wissen wollte. Die Antwort zusammengefasst ist nun:
    Entweder auf null setzen oder ne neue (leere - in meinem Fall) Instanz zuweisen.

    🙂


Log in to reply