Go 1.3 垃圾收集器保留服务器内存
理解问题
处理不规则流量连接的 TCP 服务器正在使用大量系统内存不会被释放回操作系统。当在同一台机器上运行多个服务器时,这种行为会出现问题,因为内存资源可能会随着时间的推移而耗尽。
背景
Go 的垃圾收集器 (GC) 会释放未使用的堆内存,但它不会释放未使用的堆内存。不要总是缩小进程的虚拟地址空间。在 Windows 平台上,这是不可能的。即使在基于 Unix 的系统上,Go 也会使用系统调用来通知操作系统可以回收未使用的堆内存,但这需要时间(最多 7 分钟)。
分析
基于从 Go 社区论坛收集的信息来看,该问题可能与以下因素有关:
-
Go 没有释放所有内存到操作系统: Go 只释放堆变量; goroutine 堆栈不会被释放。
-
延迟内存释放: 内存在被 GC 标记为空闲后可能不会立即返回到操作系统。还需要进行操作系统扫描,这可能需要长达 7 分钟的时间。
-
过度报告的内存使用情况:并非所有分配的内存都是“真实”内存。有些可能被运行时使用,但程序不会使用,让操作系统来处理。
潜在的解决方案
-
显式内存释放:强制垃圾使用runtime.GC()进行收集并使用显式释放内存给操作系统runtime.FreeOSMemory.
限制
- 应谨慎使用runtime.GC(),因为它会影响性能。
- runtime.FreeOSMemory 只能工作如果 GC 已运行。
- Goroutine 堆栈内存将不会被占用已发布。
致谢
- Dmitri Vyukov(Go 开发者)提供了有关该问题的重要见解。
以上是为什么我的Go 1.3服务器不将内存释放回操作系统?的详细内容。更多信息请关注PHP中文网其他相关文章!