# Flyweight-Pattern verhält sich unerwartet



## Carol (13. Apr 2011)

Hallo,

mich plagt eine Frage zum Entwurfsmuster "Fliegengewicht" (Flyweight). Ich habe ein Beispiel programmiert, das eine leichtgewichtige und eine schwergewichtige Variante hinsichtlich Speicherbedarf und Laufzeit vergleicht. 
Das Programm macht folgendes: 
1) Schwergewichtige Variante: einen Wald aus schwergewichtigen Bäumen, die ihren Zustand selbst speichern, erzeugen.
2) Leichtgewichtige Variante: einen einzigen leichtgewichtigen Baum ohne eigenen Zustand erzeugen und die Zustände der Instanzen in einem Array in einem BaumManager speichern.
3)  jeweils Speicher mit einer explizit angeforderten Garbage Collection aufräumen, je einen Wald gemäß Varianten 1) und 2) erzeugen und die Zustände der Reihe nach ausgeben. Laufzeit und Speicherbedarf messen.
Für Interessierte habe ich die Quellen als JAR-File angehängt.

Ich hätte nun erwartet, dass die leichtgewichtige Variante weniger Speicher braucht und aufgrund nicht so häufig notwendiger Garbage Collection auch schneller ist. Jedoch beobachte ich häufig das Gegenteil, manchmal braucht die schwergewichtige Variante angeblich sogar 0 Bytes Speicher und nur gelegentlich wird meine Erwartung bestätigt. Das kann ich mir nicht erklären. 
Ist das Flyweight-Pattern nun doch nicht so effizient wie behauptet, ein Fehler in meiner Implementierung oder liegt das am Java-Laufzeitsystem (JRE 1.6 unter Linux, Windows und Mac)?

Danke im Voraus,
Carol


----------



## Marco13 (13. Apr 2011)

(Noch) nicht getestet, aber... : Wie mist... äh... misst du denn den Speicherverbrauch?


----------



## Carol (13. Apr 2011)

Hallo,

indem ich Runtime.getRuntime().freeMemory() vor und nach der betrachteten Operation aufrufe. Das liefert mir jeweils den reservierten, aber noch freien Speicher. Anschließend ermittle ich den Unterschied.

Carol


----------



## AmunRa (14. Apr 2011)

Carol hat gesagt.:


> jeweils Speicher mit einer explizit angeforderten Garbage Collection aufräumen,



ICh vermute mal, dass das ganze daran liegt, da du auch mit System.gc() nicht den Garbage Collector startest, sondern ihn nur bittest, dass er vl mal anfängt zum Aufräumen, was aber nicht zwingend notwendig ist.


----------



## Marco13 (14. Apr 2011)

Wie verläßlich und genau freeMemory() ist, weiß ich im Moment zwar nicht, aber ich würde ehrlich gesagt keinen cent drauf verwetten, dass der dort zurückgegebene Wert _irgendeine_ Aussagekraft hat. (Das ist vielleicht "zu drastisch" formuliert, aber man sollte sich wirklich nicht darauf verlassen). Lass das ganze mal in der jVisualVM laufen (ist beim JDK dabei), damit kriegt man genauere Informationen - auch _wofür_ der Speicher tatsächlich verwendet wird.


----------



## maki (14. Apr 2011)

freeMemory() ist gut um zu verwirren, macht nämlich genau das was der Name sagt: gibt den freien Speicher zurück. 
Falls die VM den Speicher erhöht (limit Xmx), zeigt free Memory plötzlich mehr freien Speicher an, obwohl meist mehr Speicher belegt ist, sonst hätte die VM ihn wohl nicht erhöht.

Wenn du messen willst, nimm einen Profiler wie zB. VisualVM.


----------

