【发布时间】:2018-04-22 07:15:21
【问题描述】:
我写了一个简单的http golang webserver来测试Go垃圾收集(释放不可访问指针的内存),但是在strees测试中,我知道它消耗了过多的ram。
根据question/answers 的说法,我发现 Golang 会自动进行垃圾收集,自己管理额外的内存并且不会立即将内存返回给操作系统。一些结果:
大约 5 分钟后网络服务器释放 ram。
网络服务器消耗 ram,直到达到特定级别并且请求更多连接不会获得更多内存(在我的情况下约为 4GB)
消耗 4GB 内存并不酷!所以我在我的代码中添加了一个 Goroutine,将额外的内存返回给操作系统。
代码:
type t struct{
a []string
b map[string]string
}
var x t = t{
a: []string{"1","2"},
b: make(map[string]string),
}
func handler(w http.ResponseWriter, r *http.Request) {
x := &t{}
fmt.Fprintf(w, "pong", r.URL.Path[1:])
}
func main() {
http.HandleFunc("/ping", handler)
go func(){
for {
time.Sleep(10 * time.Second)
fmt.Println("Free up memory...")
debug.FreeOSMemory()
}
}()
log.Fatal(http.ListenAndServe(":8080", nil))
}
对于压力测试我使用Apache Bench:
ab -c 100 -n 400000 http://127.0.0.1:8080/ping
我连续运行上述命令大约 10 次以检查内存使用情况。 它工作得很好,但问题是,有没有什么标准方法可以更好地释放内存!?
我知道在某些情况下,Go 自己管理内存而不是重复从操作系统释放和取回内存是很好的,但在我的情况下,5 分钟的延迟对于释放内存来说非常重要。
【问题讨论】:
-
在哪个操作系统上,以及 Go 的哪个实现和版本?细节很重要,所以请编辑您的问题以提供更多细节(以及动机和背景)。
-
顺便说一句,在大多数操作系统上,Go 进程消耗 virtual memory(在其虚拟地址空间中),而不是 RAM。 RAM 本身由 OS 内核管理,而不是由 Go 程序或运行时管理。此外,过早释放内存可能会降低性能
标签: go garbage-collection