golang 内存疑问

问题描述

初学 golang ,没太多接触编译型语言,不太了解其内存的回收机制,在并发测试 http server 时发现内存会随着测试的进行持续走高,待测试结束后该内存会一直占用不会减少。一个请求响应的周期结束后占用的内存不应被释放掉吗,还是说这里需要手动回收呢?我应该怎样去理解和解决呢?谢谢

深度截图_选择区域_20200114132215.png

环境

kubuntu 19.10
go 1.13.4

相关代码

package main

import (
    "net/http"
)

func main() {
    http.ListenAndServe(":8080", nil)
}
ulimit -n 65535
ab -n 100000 -c 10000 http://127.0.0.1:8080/

类似问题:https://stackoverflow.com/que...

阅读 1.6k
1 个回答

首先,这个编译型语言关系不大,很多具有垃圾回收的语言都会遇到这个问题

其次,既然 Golang 有垃圾回收,当然就不需要你手动回收了

最后,那为什么程序的内存不会降低呢?有几种可能:

  1. Golang 的 http 库有 bug,会导致内存泄漏
  2. 内存已经被 runtime 回收,但并没有归还给操作系统
  3. 内存还没有被 runtime 回收

解决方案:

  1. 如果 http 有 bug (当然,出现的可能比较小,需要分析 http 源码),可以去给官方提 issue,等官方修复
  2. 你只看了操作系统的内存分析,并不代表程序没有进行垃圾回收,因为对于回收的内存,runtime 并不会立即归还操作系统,而是对其重用,这就避免了一些 alloc 系统调用的开销,对此你可以使用 pprof 库查看 golang 自己的 profile
  3. 垃圾回收是有代价的,所以 runtime 不会一直监视所有分配的内存,一旦不被引用就立马回收;而是周期性地进行垃圾回收。对此,你可以手动调用 runtime 库的 GC 函数来强制垃圾回收(当然这并不是什么好主意)

所以结论是,你并不需要做什么,因为你并没有做错什么

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏