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...

回答:

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

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

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

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

解决方案:

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

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

以上是 golang 内存疑问 的全部内容, 来源链接: utcz.com/p/183876.html

回到顶部