为什么内存块不会被垃圾回收器清理?

huangapple go评论88阅读模式
英文:

Why is the memory block not cleaned by the garbage collector?

问题

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。但我不明白为什么要花这么长时间来回收这块内存。我觉得我可能做错了什么非常严重的事情。

英文:
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)
}

Once I visit http://127.0.0.1:7777 4-5 times the memory used goes in to GBs.

Its been around 4-5 mins and the memory is still unclaimed by the OS. Why is this happening?

What am I doing wrong?

I am compiling this in go 1.5

> Edit : After 10 mins, the memory usage has gone down to just 50mb. But I dont understand why it takes so long to reclaim this block of memory. I feel like I am doing something horribly wrong.

答案1

得分: 2

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

据我所知,Go语言没有官方的内存保留上限。然而,在https://stackoverflow.com/q/24376817/7496656中,经过实验证实,保留内存的时间最长为9分钟(至少在2分钟后进行一次GC,然后保留7分钟)。你可以通过调用runtime.debug.FreeOSMemory()来手动触发这个过程,但通常除了调试目的外,这不是一个好主意。

英文:

Go does not release memory back to the OS immediately, even if it is reclaimed via garbage collection (GC). This is a performance improvement as it may need the memory again. You are not doing anything wrong. Without limited knowledge of the future demand and considering the overhead of compacting, freeing and allocating memory from the OS, every GC needs to make this performance trade-off. There was research into making the API the OS provides for this more effective in the context of the JVM and Linux kernel. User space OOM handling is a more recent, less ambitious Linux kernel development that could be used by a GC to more early release memory when it is most needed.

As far as I know there is no official upper limit for how long Go keeps memory. However in https://stackoverflow.com/q/24376817/7496656 it was experimentally verified to be 9 minutes (a GC which occurs at least after 2 minutes + 7 minutes holding memory in reserve).

You can manually trigger this by calling runtime.debug.FreeOSMemory(), however this is usually not a good idea except for debugging purposes.

huangapple
  • 本文由 发表于 2015年9月27日 03:09:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/32800952.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定