【发布时间】:2016-09-19 20:07:48
【问题描述】:
我在 []byte 类型的 compressedbytes 中接收到压缩的 ASCII 文本字节。我面临的问题是,下面的过程占用了大量内存,在函数结束后没有被释放,并且在程序的整个运行时一直被占用。
b := bytes.NewReader(compressedbytes)
r, err := zlib.NewReader(b)
if err != nil {
panic(err)
}
cleartext, err = ioutil.ReadAll(r)
if err != nil {
panic(err)
}
我注意到正在使用的类型是bytes.Buffer,并且该类型具有Reset() 和Truncate() 函数,但它们都不允许释放曾经被占用的内存。
Reset() 的 documentation 声明如下:
Reset 将缓冲区重置为空,但它保留底层存储以供将来写入使用。重置与截断(0)相同。
如何取消设置缓冲区并再次释放内存? 在需要 2 小时的运行期间,我的程序需要大约 50MB 的内存。当我导入 zlib 压缩的字符串时,程序需要 200 MB 内存。
感谢您的帮助。
=== 更新
我什至为解压创建了一个单独的函数,并在程序从该函数返回但没有成功后手动使用runtime.GC() 调用垃圾收集器。
// 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
}
【问题讨论】:
-
使用 b.WriteTo(os.stdout) 排空缓冲区怎么样?
-
你如何测量内存使用情况?
-
我在此语句前后放置了一个暂停(等待用户输入),并观察其间的进程内存增长。我在“WorkingSetSize”和“PrivateBytes”列的 SysInternals ProcessExplorer 中检查它。
-
感谢 khrm,好主意 - 我尝试添加
b.WriteTo(ioutil.Discard)没有成功。 -
@JohnGalt 这不是检查内存是否被 GC 收集的正确方法。别担心了。 GC 收集未使用的内存,可能会也可能不会将其交还给操作系统,这很好。