1 回答

TA贡献1821条经验 获得超4个赞
这里发生了很多事情。
首先,使用 Go 版本 1.14.2,您的程序对我来说运行良好。它似乎没有泄漏内存。
其次,即使我故意通过将循环大小增加到 100 并将结果保存在数组中来制造内存泄漏,我也只使用了大约 100 MB 的内存。
第三,您不应该使用 Activity Monitor 或任何其他操作系统级别的工具来检查 Go 程序中的内存泄漏。操作系统内存管理是一个非常复杂的话题,操作系统工具旨在帮助您确定程序如何影响整个系统,而不是程序中发生了什么。
具体来说,macOS“Real Memory”(类似于 RSS,驻留集大小)包括程序不再使用但操作系统尚未收回的内存。当垃圾收集器释放内存并告诉操作系统它不再需要该内存时,操作系统不会立即收回它。(为什么它以这种方式工作超出了这个答案的范围。)此外,如果操作系统处于内存压力之下,它不仅可以收回程序已释放的内存,还可以收回(临时)程序的内存仍在使用但“最近”没有访问过,以便另一个急需内存的程序可以使用它。在这种情况下,即使进程实际上并没有使用更少的内存,“Real Memory”也会减少。操作系统报告的任何统计数据都不会在此处为您提供帮助。
您需要使用像expvar和expvarmonGODEBUG=gctrace=1
这样的原生 Go 设置或工具来查看垃圾收集器在做什么。
至于为什么你的程序在限制时会耗尽内存,请记住,默认情况下,Go 会构建一个动态链接的可执行文件,并且仅读取所有共享库会占用大量内存。尝试使用静态链接构建您的应用程序,CGO_ENABLED=0
看看是否有帮助。查看仅运行 1 次循环迭代时它使用了多少内存。
- 1 回答
- 0 关注
- 191 浏览
添加回答
举报