Speicherfreigabe von MemoryStream



  • hallo,

    einfaches Beispiel:

    MemoryStream myStream = new MemoryStream(100000000); //100 MB reservieren
    Thread.Sleep(500); //ein bissl warten...
    myStream.Dispose(); //eigentlich sollte hier der speicher wieder freigeben werden
    

    ja und genau das ist mein problem ... im taskmanager tut sich gar nix, erst nach dem manuellen aufruf des garbage collectors wird der speicher freigeben... obwohl der sinn einer dispose funktion ja eigentlich ist, den speicher sofort wieder freizugeben. oder lieg ich da falsch?

    wenn ja wie gebe ich "offiziell" den speicher sofort frei?

    mfg, TFTS



  • ich hab das ganze gerade nochmal mit StreamReader und StreamWriter probiert.... auch da das selbe Problem. Dafür muss es doch ne Lösung geben!!!

    Hoffe mir kann jmd weiterhelfen.

    mfg, TFTS



  • Keine Angst, der Speicher wird wieder freigegeben. Allerdings nicht sofort, sondern erst wenn das Betriebssystem Engpässe meldet, oder sonstwie Speicher haben möchte.

    Das haben wir hier @work ziemlich durchexerziert - bei der Migration einer VB6 Anwendung nach .NET stellte sich heraus dass die Anwendung immer mehr (freien) Hauptspeicher belegte und nicht mehr freigab (getestet auf rel. unbelasteten Rechnern). Daraufhin wurden Programme eingekauft, die das Framework zwingen, Speicher sofort freizugeben, mit dem letztendlichen Ergebnis, dass die Ausgaben völlig unnötig waren, da auf den stark frequentierten Maschinen sehr wohl Speicher freigegeben wurde, wenn benötigt. Fazit, das Freigabeprogramm läuft jetzt nicht mehr, weil es das System nur verlangsamt, und nichts einbringt. Nur das Geld ist futsch.

    Just my experience 😉

    EDIT:
    Wenn der MemoryStream die 100 MB als managed Ressourcen belegt, muss nicht unbedingt Dispose diese wieder freigeben. Durchaus möglich dass z.B. StreamWriter.Dispose nur die unmanaged Ressourcen sofort freigibt (Datei schliessen etc.), nicht jedoch die managed Ressourcen.



  • ja nur leider baller ich mir hier mein 1GB Ram komplett voll... und wenn er voll läuft auch meine anwendung langsamer. Gibt es denn irgendeine Möglichkeit viel Speicherplatz bereitzustellen und auf Wunsch diesen wieder freizugeben?

    (natürlich ohne den Garbage Collector manuell auszulösen)



  • Der MemoryStream ist nichts anderes als ne Klasse mit einem byte[] drin, der die Stream-Schnittstelle bereitstellt. Er benutzt also nur managed Resourcen. Referenziere den Stream nicht mehr, wird er bei Bedarf gefressen und alles ist bestens. Bei Dispose() wird er vermutlich das interne byte[] wegschmeißen und ein kleines neues Anlegen. Das byte[] wird aufgeräumt, sobald mal wieder ein GC läuft.

    Insofern macht Dispose() schon seine Arbeit. Rufe Dispose() nicht auf, das byte[] wird nicht aufgeräumt, du kriegst ne OutOfMemoryException. Rufe Dispose() auf, das byte[] wird irgendwann aufgeräumt und zwar mit Sicherheit eher, als dass eine OutOfMemoryException kommt. Was willst du mehr? Wann das .Net Framework Speicher an das Betriebssystem zurückgibt, geht dich nichts an.

    Wenn dein Programm zu viel Speicher frisst, musst du halt weniger verbrauchen... du hast nichts davon, erst ein Gig zu belegen und dann zu meinen, "hey der hätte das Gig jetzt doch eine Minute früher an das Betriebssystem zurückgeben können". Wenn deine Anwendung zwischenzeitlich 1 GB frisst, dann tut sie es und du stellst es besser ab oder musst damit leben. Der Garbage Collector kann nicht ständig den Heap vergrößern und wieder verkleinern, dann fragmentiert der virtuelle Adressraum und alles wird noch langsamer. Auch bei manueller Speicherverwaltung ist es schlecht "mal eben nur ganz kurz" ein Gigabyte mehr zu belegen als normal.



  • TFTomSun schrieb:

    hallo,

    einfaches Beispiel:

    MemoryStream myStream = new MemoryStream(100000000); //100 MB reservieren
    Thread.Sleep(500); //ein bissl warten...
    myStream.Dispose(); //eigentlich sollte hier der speicher wieder freigeben werden
    

    ja und genau das ist mein problem ... im taskmanager tut sich gar nix, erst nach dem manuellen aufruf des garbage collectors wird der speicher freigeben... obwohl der sinn einer dispose funktion ja eigentlich ist, den speicher sofort wieder freizugeben. oder lieg ich da falsch?

    wenn ja wie gebe ich "offiziell" den speicher sofort frei?

    mfg, TFTS

    Der Speicher wird wieder freigegeben das steht fest, wie die anderen Kollegen das auch schon sagten.

    Der GC ist ein Hintergrundprozess mit niedriger Priorität und sucht nach Objekten die nichtmehr referenziert werden. Er braucht eben mal ne Weile um über alle Objekte einer Anwendung zu Prüfen.

    http://www.galileocomputing.de/openbook/visual_csharp/visual_csharp_04_005.htm


Anmelden zum Antworten