我收到compressedbytes[]byte 类型的压缩 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()状态如下:重置将缓冲区重置为空,但它保留底层存储以供将来写入使用。重置与截断(0)相同。如何取消设置缓冲区并再次释放内存?我的程序在需要 2 小时的运行期间需要大约 50MB 的内存。当我导入 zlib 压缩的字符串时,程序需要 200 MB 内存。谢谢你的帮助。=== 更新我什至为解压创建了一个单独的函数,并runtime.GC()在程序从该函数返回但没有成功后手动调用垃圾收集器。// unpack decompresses zlib compressed bytesfunc 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}
2 回答
ibeautiful
TA贡献1993条经验 获得超5个赞
有些事情要清楚。Go 是一种垃圾收集语言,这意味着当这些变量变得无法访问时,垃圾收集器会自动释放变量分配和使用的内存(如果您有另一个指向该变量的指针,它仍然算作“可访问”)。
释放的内存并不意味着它会返回给操作系统。释放内存意味着可以回收内存,如果需要,可以将其重用于另一个变量。因此,从操作系统来看,您不会仅仅因为某些变量变得无法访问而立即看到内存减少,并且垃圾收集器检测到这一点并释放了它使用的内存。
但是,如果一段时间(通常是 5 分钟左右)不使用,Go 运行时会将内存返回给操作系统。如果在此期间内存使用量增加(并且可选地再次缩小),则内存很可能不会返回给操作系统。
如果您等待一段时间并且不再分配内存,则释放的内存最终将返回给操作系统(显然不是全部,但未使用的“大块”将是)。如果您不能等待这种情况发生,您可以调用debug.FreeOSMemory()
强制执行此行为:
FreeOSMemory 强制进行垃圾收集,然后尝试将尽可能多的内存返回给操作系统。(即使不调用它,运行时也会在后台任务中逐渐将内存返回给操作系统。)
- 2 回答
- 0 关注
- 341 浏览
添加回答
举报
0/150
提交
取消