Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Laufzeit Garbagecollector

12 views
Skip to first unread message

Jörg

unread,
May 1, 2013, 7:44:41 AM5/1/13
to
Hallo,

ich habe mit einem Kollegen über die Verwendung einer Schätzung bei der
Konstruktion der StringBuilder diskutiert.

StringBuilder sb = new StringBuilder(1024);

Ich verwende stets Schätzwerte für die initial Größe, damit der Puffer
nicht ständig umkopiert wird und den Garbagecollector unter Last nimmt.

Gibt es Informationen über die ungefähre Laufzeit bzw. Ordnung der
Laufzeit des Garbagecollectors ? Meine Vorstellung war bisher, dass
verwaiste Objekte und verwaiste Teilgraphen im Objekt-Raum gesucht und
gelöscht werden, wobei dann gegebenenfalls entstandene Lücken zu
größeren Freiräumen zusammen gefasst werden.

Ist die Laufzeit eher linear oder quadratisch oder noch anders ?

Grüße

Jörg

Florian Weimer

unread,
May 1, 2013, 8:52:15 AM5/1/13
to
* J�rg:

> Ist die Laufzeit eher linear oder quadratisch oder noch anders ?

Anders, und das auch nach stark implementationsabh�ngig. Hotspot
besitzt drei grundverschiedene Algorithmen, die selbst noch in
zahlreichen Varianten betrieben werden k�nnen. Kollektoren sollten
normalerweise Kosten proportional zu den noch genutzten Objekten im
Heap haben (oder deren Platzbedarf), aber das ist nicht bei allen
Kollektoren der Fall.

Bei StringBuilder entstehen die Kosten mit GC-Bezug mittelbar dadurch,
da� der Zeitpunkt der n�chsten Minor Collection n�her r�ckt, prim�r
durch den Platzverbrauch der char[]-Objekte. Wie teuer diese Minor
Collection tats�chlich ist, h�ngt davon ab, was das Programm sonst
noch so treibt. Die Allokation und Deallokation der char[]-Objekte
selbst sind nahezu kostenfrei, insbesondere im Vergleich zu den
Kopieroperationen.

Vom GC-Standpunkt aus ist die Gr��enanbgabe jedenfalls nur dann
sinnvoll, wenn die tats�chlich ben�tigte Kapazit�t nur sehr selten
gr��er als die angegebene ist und der StringBuilder am Ende mindestens
zur H�lfte gef�llt ist. Au�erhalb dieses Fensters allokiert die
automatische Gr��enanpassung weniger.
Message has been deleted

Marcel Müller

unread,
May 1, 2013, 10:39:03 AM5/1/13
to
Hallo,

On 01.05.2013 13:44, Jörg wrote:
> ich habe mit einem Kollegen über die Verwendung einer Schätzung bei der
> Konstruktion der StringBuilder diskutiert.
>
> StringBuilder sb = new StringBuilder(1024);
>
> Ich verwende stets Schätzwerte für die initial Größe, damit der Puffer
> nicht ständig umkopiert wird und den Garbagecollector unter Last nimmt.

so tickt das nicht. Der GC muss den Stringbuilder sowieso wegräumen; das
ist eine typisches temporäres Objekt. Únd wenn Du ihn unnötig groß
machst muss er /mehr/ wegräumen. Das dauert zwar nicht länger, aber wenn
Du viel Speicher allozierst, muss der GC öfter laufen. Und dadurch
erwächst ein Geschwindigkeitsnachteil.


> Gibt es Informationen über die ungefähre Laufzeit bzw. Ordnung der
> Laufzeit des Garbagecollectors ?

Typische werte liegen bei maximal 10-15% - bezogen auf die CPU-Last des
Programms selbst. Es gibt aber auch Anwendungen, wo der Wert erheblich
niedriger liegt.

> Meine Vorstellung war bisher, dass
> verwaiste Objekte und verwaiste Teilgraphen im Objekt-Raum gesucht und
> gelöscht werden, wobei dann gegebenenfalls entstandene Lücken zu
> größeren Freiräumen zusammen gefasst werden.

Nein, anders herum. Noch referenzierte Objekte werden in die
Verlängerung geschickt, und alles, was am Ende kein Zuhause hat, wird
auf einen Schlag weggeknallt. Naja, das war jetzt die extra kurze
Beschreibung.

> Ist die Laufzeit eher linear oder quadratisch oder noch anders ?

Linear mit was? Mit der Anzahl der zu löschenden Objekte? Nein, das ist
sogar grob constant time. Spannender ist vielmehr, wie viele Objekte
noch gehalten werden müssen. Und ein weiterer, wichtiger Punkt ist, wie
oft der GC ran muss. Je exzessiver ein Programm temporäre Objekte
alloziert, desto öfter muss der GC (im Mittel) klar Schiff machen. Das
ist, wenn Du so willst eine lineare Skalierung.

Das bedeutet, wenn Du wirklich etwas gutes für den GC tun willst, dann
solltest Du möglichst wenige temporäre Objekte erzeugen. Also z.B. nicht
in inneren Schleifen. Ein hundertmal benutzter StringBuilder ist immer
besser als hundert einzelne mit exakt passender Größe.

Das andere Extrem, alles und jedes Objekt irgendwo zu Cachen geht aber
auch nach hinten los, denn dann hat man jede Menge Objekte mit langer
Lebensdauer, die ständig den Speicher zumüllen. Außerdem leidet dann
u.U. die Thread-Lokalität des Speichers und damit auch die CPU
Cache-Effizienz.

Aber es gibt noch viele weitere Einflussfaktoren. So können GCs
typischerweise besonders schlecht mit Objekten mittlerer Lebensdauer
umgehen. Am effektivsten arbeiten sie mit Objekten, die entweder ewig
leben oder weniger lange als die Zeit zwischen zwei kleinen GC-Läufen.
Deswegen sind Caches mit einer eher kurzen Speicherzeit zuweilen
kontraproduktiv.


Marcel
0 new messages