当前位置: 首页 > 面试题库 >

一旦被字节占用就无法释放内存

晏树
2023-03-14
问题内容

我收到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()状态如下:

重置会将缓冲区重置为空,但会保留基础存储以供将来的写操作使用。重置与Truncate(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
}

问题答案:

一些事情要清除。Go是一种垃圾回收语言,这意味着当这些变量变得不可访问时,垃圾回收器会自动释放变量分配和使用的内存(如果您有另一个指向该变量的指针,则仍视为“可访问”)。

释放的内存并不意味着将其返回给操作系统。释放的内存意味着可以回收该内存,并在需要时将其重新用于另一个变量。因此,从操作系统中,您不会仅由于某些变量变得不可访问而垃圾回收器检测到此问题并释放了它使用的内存,就不会立即看到内存减少。

但是,如果Go运行时一段时间(通常约5分钟)不使用,它将把内存返回给OS。如果在此期间内存使用量增加(并且有选择地再次缩小),则很有可能不会将内存返回给操作系统。

如果您等待一段时间而不重新分配内存,则释放的内存最终将返回给OS(显然不是全部,而是未使用的“大块”)。如果您迫不及待想要发生这种情况,可以致电debug.FreeOSMemory()强制执行以下操作:

FreeOSMemory强制执行垃圾回收,然后尝试将尽可能多的内存返回给操作系统。(即使未调用,运行时也会在后台任务中将内存逐步返回给操作系统。)



 类似资料:
  • 所以我试图修改我的控制器类中的一些圆,我已经将这些圆链接到我的fxml文件圆,但是当我试图将它们添加到圆数组中以便于管理时,它们似乎失去了它们的引用。例如,我有: 上述方法成功地在给定坐标中弹出一个圆。但是,以下方法不起作用: 这不管用!尝试了数组尝试了数组列表尝试了Linkedlist,对Circle1的引用丢失了。我是JAVAFX的新手,所以这可能是一个简单的修复,但我试着研究了一点,尝试了不

  • 使用SXSSFWorkbook读取Excel,1W行数据,188列(测试时只有前16列有数据) 读取操作完成后,JVM中存在大量的org.apache.xmlbeans.impl.store.Xobj$AttrXobj org.apache.xmlbeans.impl.store.Xobj$ElementXob类的实例,很长时间内不会被GC 我尝试过使用SAX事件驱动解析Excel、Streami

  • 我有一个烧瓶后端和一个反应前端。Flask后端是一个将与其他微服务通信的API。在开发中,我的React前端在localhost:3000上运行,Flask应用程序在localhost:5000上运行。显然,这些端口是不同的,默认情况下会抛出CORS错误。所以我添加了Flask_CORS并允许来自localhost:3000的流量。这很有效,我现在可以为GET和POST请求提供服务。 然后,我将F

  • 在分布式Java桌面应用程序通过JDBC访问的特别请求的DB2表中,我每天都会多次收到以下场景: > 客户机A想要插入新的寄存器,并在表上获得一个IX锁,X锁在每个新行中; 其他客户端想要执行SELECT,被授予表上的IS锁,但应用程序卡住了; 客户机A继续工作,但是插入和更新查询没有被提交,锁没有被释放,并且它继续收集X个锁到每一行; 客户端 A 退出,其工作未提交。其他客户端最终获取其 SEL

  • 我正在使用相机意图启动应用程序中的相机,但一旦意图被激发,就被激发,我甚至还没有拍摄到一张照片。 当我拍摄一张照片时,选择它并返回到我的活动中,根本不会被调用 下面是我如何发射相机 为什么只在相机意图启动后调用?

  • 由于我的项目的性质,我发现自己经常从QuerySet中提取片段,如下所示: 但是这给我留下了一个问题,就是如何用我选择的元素做一些事情,因为任何类型的。更新()或。切片后filter()不起作用。 我知道有几种方法可以绕过它,但它们都很混乱和混乱,严重降低了代码的可读性,特别是当我不得不经常这样做的时候。 克服限幅滤波器限制的最佳方法是什么?