为什么垃圾收集器没有清理内存块?

时间:2015-09-26 19:09:06

标签: go

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分钟,操作系统仍然无人认领内存。为什么会这样?

我做错了什么?

我正在编写这个1.5

  

编辑:10分钟后,内存使用量降至50mb。但我不明白为什么要回收这段内存需要这么长时间。我觉得我在做一些可怕的错误。

1 个答案:

答案 0 :(得分:1)

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

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

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