golang 内存疑问
问题描述
初学 golang
,没太多接触编译型语言,不太了解其内存的回收机制,在并发测试 http server
时发现内存会随着测试的进行持续走高,待测试结束后该内存会一直占用不会减少。一个请求响应的周期结束后占用的内存不应被释放掉吗,还是说这里需要手动回收呢?我应该怎样去理解和解决呢?谢谢
环境
kubuntu 19.10
go 1.13.4
相关代码
package mainimport (
"net/http"
)
func main() {
http.ListenAndServe(":8080", nil)
}
ulimit -n 65535ab -n 100000 -c 10000 http://127.0.0.1:8080/
类似问题:https://stackoverflow.com/que...
回答:
首先,这个编译型语言关系不大,很多具有垃圾回收的语言都会遇到这个问题
其次,既然 Golang 有垃圾回收,当然就不需要你手动回收了
最后,那为什么程序的内存不会降低呢?有几种可能:
- Golang 的 http 库有 bug,会导致内存泄漏
- 内存已经被 runtime 回收,但并没有归还给操作系统
- 内存还没有被 runtime 回收
解决方案:
- 如果 http 有 bug (当然,出现的可能比较小,需要分析 http 源码),可以去给官方提 issue,等官方修复
- 你只看了操作系统的内存分析,并不代表程序没有进行垃圾回收,因为对于回收的内存,runtime 并不会立即归还操作系统,而是对其重用,这就避免了一些 alloc 系统调用的开销,对此你可以使用 pprof 库查看 golang 自己的 profile
- 垃圾回收是有代价的,所以 runtime 不会一直监视所有分配的内存,一旦不被引用就立马回收;而是周期性地进行垃圾回收。对此,你可以手动调用 runtime 库的 GC 函数来强制垃圾回收(当然这并不是什么好主意)
所以结论是,你并不需要做什么,因为你并没有做错什么
以上是 golang 内存疑问 的全部内容, 来源链接: utcz.com/p/183876.html