【问题标题】:Why is the memory block not cleaned by the garbage collector?为什么垃圾收集器没有清理内存块?
【发布时间】:2015-09-26 19:09:06
【问题描述】:
package main

import (
        "fmt"
        "net/http"
        "runtime"
)

func handler(w http.ResponseWriter, r *http.Request) {
       largeMemAlloc := make([]int, 100000000)
       largeMemAlloc[1] = 100//lol
       fmt.Fprintf(w, "hi from handler")
       runtime.GC()
}

func main() {
       http.HandleFunc("/", handler)
       http.ListenAndServe(":7777", nil)
}

一旦我访问http://127.0.0.1:7777 4-5 次使用的内存进入 GB。

大约 4-5 分钟后,内存仍未被操作系统占用。为什么会这样?

我做错了什么?

我在 go 1.5 中编译这个

编辑:10 分钟后,内存使用量降至 50mb。但是我不明白为什么回收这块内存需要这么长时间。我觉得我做错了什么。

【问题讨论】:

  • Go 不会立即将内存释放回操作系统——因为使用大块内存的程序通常会再次使用它们。只有在大约 7 - 10 分钟后才会释放未使用的内存 - 请参阅此处stackoverflow.com/questions/24376817/…
  • 我明白了,非常感谢。
  • @elithrar 这是一个很好的解释!介意也为 Gen 的问题提供答案吗?

标签: go


【解决方案1】:

Go 不会立即将内存释放回操作系统,即使它是通过垃圾回收 (GC) 回收的。这是一种性能改进,因为它可能再次需要内存。你没有做错任何事。如果对未来需求的了解有限,并考虑到从操作系统压缩、释放和分配内存的开销,每个 GC 都需要进行这种性能权衡。有研究使操作系统提供的 API 在 JVM 和 Linux 内核的上下文中更有效。用户空间 OOM 处理是较新的、不那么雄心勃勃的 Linux 内核开发,GC 可以使用它在最需要的时候更早地释放内存。

据我所知,Go 保留内存的时间没有官方上限。但是在Go 1.3 Garbage collector not releasing server memory back to system 中,它被实验验证为 9 分钟(至少在 2 分钟后发生的 GC + 7 分钟保留内存)。

您可以通过调用runtime.debug.FreeOSMemory() 手动触发此操作,但是这通常不是一个好主意,除非出于调试目的。

【讨论】:

    猜你喜欢
    • 2015-04-10
    • 1970-01-01
    • 1970-01-01
    • 2021-12-18
    • 1970-01-01
    • 2014-12-07
    • 1970-01-01
    • 2013-01-08
    • 1970-01-01
    相关资源
    最近更新 更多