Nicht der freie Speicher einmal besetzt von bytes.Puffer
Erhalte ich die bytes des komprimierten ASCII-text in compressedbytes
Typ []byte. Das problem, das ich konfrontiert ist, dass Sie die folgende Prozedur nimmt viel Speicher, der nicht freigegeben, wenn die Funktion bis zum Ende und bleibt besetzt, die während der gesamten Laufzeit des Programms.
b := bytes.NewReader(compressedbytes)
r, err := zlib.NewReader(b)
if err != nil {
panic(err)
}
cleartext, err = ioutil.ReadAll(r)
if err != nil {
panic(err)
}
Bemerkte ich, dass der Typ in Gebrauch ist bytes.Buffer
und dieser Typ hat die Reset()
und Truncate()
Funktionen, aber keiner von Ihnen ermöglicht, den Speicher frei, das ist einmal belegt.
Den Dokumentation von Reset()
besagt Folgendes:
Reset setzt den Puffer leer zu sein, aber es behält den zugrunde liegenden Speicher für die Nutzung von Zukunft schreibt. Reset ist das gleiche wie Truncate(0).
Wie kann ich entfernt den Puffer und den freien Speicher wieder auf?
Mein Programm benötigt etwa 50 MB Speicher, während das laufen, das dauert 2h. Wenn ich importieren, die Zeichenfolgen, die die zlib-komprimiert das Programm benötigt 200 MB Speicher.
Vielen Dank für Ihre Hilfe.
=== Update
Ich auch eine separate Funktion für die Dekompression und rufen Sie den garbage collector manuell mit runtime.GC()
nach dem Programm gibt aus, dass die Funktion ohne Erfolg.
//unpack decompresses zlib compressed bytes
func unpack(packedData []byte) []byte {
b := bytes.NewReader(packedData)
r, err := zlib.NewReader(b)
if err != nil {
panic(err)
}
cleartext, err := ioutil.ReadAll(r)
if err != nil {
panic(err)
}
r.Close()
return cleartext
}
- Was über die Entwässerung der Puffer mit b.Writecontentto(os.stdout) ?
- Wie sind Sie mit der Messung der Speicherauslastung?
- Ich legte eine pause (warten auf eine Benutzereingabe) vor und nach dieser Aussage und beobachten Sie den Prozess-Speicher dazwischen wachsen. Ich schau es im SysInternals ProcessExplorer in der Spalte "WorkingSetSize" und "PrivateBytes".
- Dank khrm, gute Idee - ich habe versucht, hinzufügen
b.WriteTo(ioutil.Discard)
ohne Erfolg. - Dies ist nicht der richtige Weg, um zu überprüfen, wenn der Speicher gesammelt werden, der GC. Aufhören, sich sorgen. Der GC speichert ungenutzte Speicher und möglicherweise oder möglicherweise nicht es zurück zu dem OS was in Ordnung ist.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Einige Dinge zu klären. Go ist ein garbage-Sprache, was bedeutet, dass der Speicher reserviert und von Variablen wird automatisch vom garbage collector freigegeben, wenn diese Variablen nicht erreichbar sein (wenn Sie einen anderen Zeiger auf die variable, die noch zählt als "erreichbar").
Freigegebenen Speicher bedeutet nicht, dass es an das Betriebssystem zurückgegeben wird. Befreit-Speicher bedeutet, dass der Speicher rückgewonnen werden kann, wiederverwendet, für andere variable, wenn es notwendig ist. Also von dem Betriebssystem, das Sie nicht sehen-Speicher Verringerung richtigen Weg, nur weil einige variable wurde nicht erreichbar und der garbage collector erkannt und diese freigegebenen Speicher verwendet es.
Gehen die Laufzeit wird jedoch die Rückkehr Speicher für das OS, wenn es nicht verwendet wird, für einige Zeit (in der Regel etwa 5 Minuten). Wenn der Speicher Nutzung erhöht sich während dieser Zeit (und Optional wieder schrumpft), der Speicher wird wahrscheinlich nicht an das Betriebssystem zurückgegeben.
Wenn Sie warten einige Zeit und nicht die Speicher wieder freigegeben Speicher an das Betriebssystem zurückgegeben irgendwann (natürlich nicht alle, aber ungenutzte "großen Brocken" werden). Wenn Sie können nicht warten, bis dies geschehen, können Sie sich telefonisch
debug.FreeOSMemory()
um dieses Verhalten zu erzwingen:Check heraus, diese Art von alten, aber wirklich informativ ist die Frage+Antworten:
Go 1.3 Garbage collector Sie nicht freigeben server-Speicher wieder auf system
Es wird schließlich freigegeben, wenn keine Referenzen mehr, Gehen hat eine ziemlich anständige GC.