Garbage Collector aufrufen

Hi,

in Anwendung, in der ich doch des öffteren Objekte erstelle (is ja schließlich Java) wo auch der Zugriff häufig ist, geht das doch ein Wenig auf die Performance.
Auf den Garbage Collector kann man sich zwar begrenzt verlassen, doch wenn ich in meinem Programm weiss ‚Jetzt ist der Zeitpungt da etwa 8000 Objekte nur noch müll sind.‘ würde ich das Ding gern aufrufen.

Bei der Gelegenheit:
Wie zerstüre ich ein Objekt, so richtig mit Reccourcenfreigabe, ohne den MüllSammler?

cu Desian

Hi.

Als erstes musst du sämtliche Referenzen auf deine Objekte, die du nicht mehr brauchst vernichten, indem du ihnen beispielsweise null zuweist.
Damit weiss der Garbage Collector, dass er diese Objekte einsammeln darf.
Anschließend gibt es mit „System.gc()“ die Möglichkeit, der VM den Einsatz des GarbageCollectors zu empfehlen. So weit ich weiss, muss die VM sich aber nicht unbedingt daran halten.

Sebastian.

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

Hi,

und wie kann ich sie Konfigurieren, dass sie tut was ich ihr sage?

cu Desian

Moin

und wie kann ich sie Konfigurieren, dass sie tut was ich ihr
sage?

Gar nicht. (jedenfalls die von sun, ibm und hp nicht)

Es ist allerdings auch Blödsinn gc nach dem Löschen von vielen Objecten aufzurufen (Dabei blockiert gc das System nämlich relativ lange, wogehen die back-ground only-when-needed Strategie des sun-gc’s für viele aber _nicht_ merkbare Unterbrechnungen sorgt.)

Ausserdem wäre die Option „-server“ beim Aufruf der JVM evtl. von Vorteil.

(Oder ein 2 CPU-System so dass gc auf der anderen CPU laufen kann.)

cu

Hi,

ich stimme pumkin soweit zu, möchte aber doch noch folgendes hinzufügen:

  • den gc sollte man aus Java heraus nicht explizit aufrufen, da (zumindest in Java 1.1 und 1.2) hieraus Speicherfehler resultier(t)en (vgl. auch Bug-Liste bei sun), die schwer zu finden bzw. selbst gar nicht zu beheben sind.

  • es gibt die Möglichkeit, beim Start der VM eine minimale und maximale Heapsize zu definierne (z.B. maximal mit: -Xmx512M). Damit kann man beeinflussen, wie oft der GarbageCollector läuft - mit nicht unerheblichen Perfomance-Einfluss.
    (Aber Achtung: die maximale HeapSize nicht zu groß einstellen, sonst gehts los mit dem „Paging“ = Auslagerung auf Festplatte)

Gruß
Claudia

Zum Thema Garbage Collector konfigurieren schau dir mal folgenden Link an:

http://java.sun.com/docs/hotspot/gc/

Es gibt auch Möglichkeiten im Code den Umgang des GC mit Objekten zu beeinflussen, dazu siehe z. B. hier:

http://tutorials.beginners.co.uk/integrate_read/i/21…

Grüße, Robert

Hallo,

Es ist allerdings auch Blödsinn gc nach dem Löschen von vielen
Objecten aufzurufen (Dabei blockiert gc das System nämlich
relativ lange, wogehen die back-ground only-when-needed
Strategie des sun-gc’s für viele aber _nicht_ merkbare
Unterbrechnungen sorgt.)

Naja, manchmal ist es aber durchaus sinnvoll. Ich musste z.B. mal Bestände von Bibliotheken im Speicher analysieren. Das waren dann Tabellen mit mehreren Millionen Objekten. Da war selbst ein PC mit 1 GB Arbeitsspeicher schnell am Ende. Da half nur noch den GC per Hand an zu werfen, wenn ich eine genügend große Zahl von Objekten nicht mehr gebraucht habe. Natürlich kostet das Wegwerfen der Objekte durch den GC Rechenzeit und das System wird blockiert, aber es war allemal besser, als den PC zum swappen zu bringen. Denn sobald du in Objekten rumwurschtelst, die schon im Swap liegen, dann ist die Performance hinüber…

Aber ansonsten würde ich auch eher vom expliziten Aufruf des GCs abraten. Das System wie und wann der GC Objekte wegschmeißt ist eigentlich ziemlich intelligent und meist auch am performantesten.

mfg
deconstruct

Hallo,

So weit ich
weiss, muss die VM sich aber nicht unbedingt daran halten.

Also wenn du System.gc() aufrufst, dann wird der Garbage-Collector 100%ig angeworfen. Sobald die Methode fertig ist, hat der Garbage-Collector definitiv das weggeworfen was er wegwerfen kann.

Da ich mal ein ähnliches Problem hatte, wo das anwerfen des GCs unumgänglich war, hab ich da auch diverse Tests gemacht, die mir das so bestätig haben.

In der API-Dokumentation steht ausserdem drin:

When control returns from the method call, 
the virtual machine has made its best effort to 
recycle all discarded objects.

mfg
deconstruct

Also wenn du System.gc() aufrufst, dann wird der
Garbage-Collector 100%ig angeworfen. Sobald die Methode fertig
ist, hat der Garbage-Collector definitiv das weggeworfen was
er wegwerfen kann.

Gemäss Java-Spezifikation ist das keineswegs so. System.gc() ist Plattform und Implementationsabhängig. Wie und wann der Garbage Collector tätig wird ist nicht voraussagbar. (Ausser Du dekompilierst die Klassen und schaust mal rein, wie’s implementiert ist.

Um die plattformunabhängikeit des Codes zu bewahren sollte deshalb auf System.gc() verzichtet werden.

Gruss, Simon

Hallo,

Gemäss Java-Spezifikation ist das keineswegs so.

Doch, so stehts ja schließlich in der von mir zitierten Java-API-Spezifikation drin. Auch sagen die Leute von SUN selbst,
dass es so ist.

http://java.sun.com/docs/books/tutorial/java/data/ga…
http://java.sun.com/docs/books/tutorial/essential/sy…

mfg
deconstruct

Moi

Doch, so stehts ja schließlich in der von mir zitierten
Java-API-Spezifikation drin.

Das von dir zitierte stammt aus der sun-api-doc. Daran muss sich kein anderer halten z.b. klingt das bei der real-time JVM von HP schon ganz anders. (Ausserdem stimmts so nicht mehr, da gc mit version 1.3.0 komplett neu geschrieben wurde und man jetzt 2x aufrufen muss um sicher zu sein. Die api-doc stammt noch von 1.1.8)

cu

Hallo,

Das von dir zitierte stammt aus der sun-api-doc.
Daran muss
sich kein anderer halten z.b. klingt das bei der real-time JVM

Mein Text handelt aber auch nur von der SUN JRE :wink:
Vielleicht wurde das nicht ganz klar…
Natürlich kann das in einer anderen JVM anders sein.

von HP schon ganz anders.

Naja, das ist schon klar.

(Ausserdem stimmts so nicht mehr, da
gc mit version 1.3.0 komplett neu geschrieben wurde und man
jetzt 2x aufrufen muss um sicher zu sein. Die api-doc stammt
noch von 1.1.8)

Natürlich stimmts für SUN JVMs noch so. Die API-Dokumentation von System.gc() ist außerdem aktuell. Dass sie noch von Version 1.1.8 stammt mag durchaus sein, ist aber irrelevant, da sich auch nichts geändert hat seit damals.

Fakt ist:
Ein Aufruf von System.gc() macht eine Garbage-Collection. Und zwar vollständig und sofort. Ein zweiter Aufruf o.ä. ist nicht sicher und das ganze funktioniert absolut deterministisch. Nachdem diese Methode abgeschlossen wurde, sind alle nicht mehr referenzierbaren Objekte freigegeben.
Das steht so in der API-Doku von SUN, in der Hotspot-Doku. Dies gilt für alle möglichen GC-Generationen und -algorithmen von SUN.

14. What type of collection does a System.gc() do?
 An explicit request to do a garbage collection does a full 
 collection (both young generation and tenured generation). 
 A full collection is always done with the application paused 
 for the duration of the collection.

Quelle: http://java.sun.com/docs/hotspot/gc1.4.2/faq.html
Dies gilt natürlich nur für SUN JVMs.

mfg
deconstruct