Go的垃圾收集器未在正确的时间释放内存 [英] Go's Garbage collector isn't releasing memory at the right time

查看:121
本文介绍了Go的垃圾收集器未在正确的时间释放内存的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写了一个简单的http golang网络服务器来测试Go垃圾回收(释放无法访问的指针的内存),但是在strees测试中,我知道它消耗了过多的内存.

I wrote a simple http golang webserver to test the Go garbage collection (releasing memory of inaccessible pointers), But in strees testing ,I understand it consumes excessive ram.

根据一些 question/答案,我发现Golang会自动进行垃圾回收,自己管理多余的内存,并且不会立即将内存返还给OS.一些结果:

According to some question/answers, I found out Golang does garbage collection automatically, manage the extra memory itself and doesn't get back memory to OS at once. Some results:

  • Web服务器在大约5分钟后释放ram.

  • The webserver release ram after about 5mins.

Web服务器会消耗ram直到达到特定级别并且请求更多连接不会获得更多内存(在我的情况下约为4GB)

The webserver consumes ram until it gets up to specific level and requesting more connections not gets more memory(about 4GB in my case)

消耗4GB的内存并不酷!因此,我在代码中添加了Goroutine,以将额外的内存返回给OS.

Consuming 4GB of ram isn't cool! So i added a Goroutine to my code that gets the extra memory back to OS.

代码:

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 :

For stress testing i use Apache Bench:

ab -c 100 -n 400000 http://127.0.0.1:8080/ping

我连续10次以上运行命令以检查ram的使用情况. 它工作得很好,但是问题是,是否有任何标准方法可以更好地释放内存!

I ran above command about 10 times continuously to check the ram usage. It works very well, But the problem is, Is there any standard way that Go releases the memory better!?

我知道在某些情况下,Go可以自己管理内存,而不是从操作系统中重复释放和获取内存,这是件好事.但是在我的情况下,延迟5分钟对于释放内存非常重要.

I know in some cases, it's good that Go manages the memory itself instead of repetitive releasing and getting back memory from OS, But in my case, 5 minutes delay is very much to releasing memory.

推荐答案

您可能想调用 runtime/debug

但是您可能不应该.尝试针对您的特定应用程序和用途来调整GC(也许使用 SetGCPercent ) .经常使用FreeOSMemory可能会降低性能,因此请务必进行基准测试.

But you probably should not. Try instead to tune the GC for your particular application and usage (perhaps using SetGCPercent). It is likely that using FreeOSMemory too often would decrease performance, so be sure to benchmark.

请注意,垃圾收集实现在Go的最新版本中有所改进,并且在各种Go实现中有所不同(例如,在 GCC Go ).

不要混淆RAM的使用( RAM 由操作系统内核管理,而不是通过Go进程),虚拟内存 RSS 崩溃.

Don't confuse RAM usage (the RAM is managed by your OS kernel, not by your Go process), virtual memory, virtual address space. Read about RSS, demand paging, thrashing.

有关垃圾回收技术的概述,请阅读 GC手​​册 .

For an overview of garbage collection techniques, read The GC Handbook.

为更好地了解操作系统,请阅读> 操作系统:三篇简单文章

For a better understanding of OSes, read Operating Systems: Three Easy Pieces

另请参见 Linux吞噬了我的RAM .

这篇关于Go的垃圾收集器未在正确的时间释放内存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆