【问题标题】:How to force release (garbage collect) a slice? [closed]如何强制释放(垃圾收集)切片? [关闭]
【发布时间】:2021-03-21 17:52:10
【问题描述】:

我正在尝试完全释放切片,因此内存会回到操作系统;但是,当我尝试通过 slice = nil 取消引用它时,什么也没有发生。

我也尝试过使用runtime.GC()debug.FreeOSMemory(),但它们都没有帮助。

这是我的代码:

package main

import (
    "fmt"
    "runtime"
    "runtime/debug"
)

func printMemStats(stage string) {
    var m runtime.MemStats
    runtime.ReadMemStats(&m)
    fmt.Println(stage, m.Sys/1024/1024)
}

func main() {
    printMemStats("before")
    a := make([]uint64, 1000000000)
    printMemStats("after")
    a = nil
    runtime.GC()
    debug.FreeOSMemory()
    printMemStats("remove")
    _ = a // get rid of the unused variable error
}

结果:

before 68
after 7997
remove 7998

而预期的输出是:

before 68
after 7997
remove 68

【问题讨论】:

  • 你应该使用m.Alloc,而不是m.Sys
  • 可以,但是系统内存没有释放。它最终占用的内存与分配内存后占用的内存一样多。
  • 从操作系统分配和释放内存是昂贵的。每次释放某些东西时将内存还给操作系统是浪费时间,因为当程序再次需要一些内存时,它会立即再次分配。
  • 做了释放它,Golang 将使用这个空闲内存进行下一次分配。
  • 最好提出导致您认为需要将内存释放给操作系统的原始问题。

标签: go


【解决方案1】:

首先,你真的应该只在极端例外情况下使用debug.FreeOSMemory()。 Go 是管理内存的,因此您无法像在 C/C++ 中那样控制行为。

官方documentation表示:

将尽可能多的内存归还给操作系统。

这并不能保证它总是会立即返回所有内容,因为内存分配很昂贵,并且在完全无视性能的情况下最小化内存占用是不明智的。这个post 详细解释了为什么你不应该在生产环境中使用它。

【讨论】:

    猜你喜欢
    • 2015-02-12
    • 2018-10-05
    • 1970-01-01
    • 2011-12-01
    • 2011-05-14
    • 2011-04-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-16
    相关资源
    最近更新 更多