【问题标题】:goroutine not returning memory to OSgoroutine 没有将内存返回给操作系统
【发布时间】:2020-03-09 22:30:32
【问题描述】:

我想确保我的 pod 在内存不足时不会重新启动。现在我看到容器的 heapMem 使用率很低,但 SysMem 的使用率已增加到 4Gb,并且不会随着 heapMem 减少。我相信 GC 应该把这个返回给 OS。

Prometheus 统计数据用于监控 go_memstats_alloc_bytesgo_memstats_sys_bytes。我也看到go_memstats_gc_cpu_fraction 不会增加加班时间。

我错过了什么吗?是否有可能的内存泄漏?

【问题讨论】:

  • 首先,垃圾收集器的工作是回收垃圾和重用内存,它不会将任何东西释放回操作系统。 MemStat.Sys 字段记录为 [measuring] the virtual address space reserved by the Go runtime [...] It's likely that not all of the virtual address space is backed by physical memory at any given moment。该图表没有告诉我们任何信息,只是看起来您的活动爆发可能会占用您所有的内存。
  • 你可以尝试设置madvdontneed=1(详情:golang.org/doc/go1.12#runtime)。基本上在 Linux 中,golang 使用 madvfree 将内存释放回操作系统,除非操作系统处于内存压力之下,否则大多数情况下操作系统会忽略该内存。你也可以试试 go 1.13,它应该更积极地将内存返回给操作系统:golang.org/doc/go1.13#runtime

标签: go garbage-collection containers prometheus


【解决方案1】:

从图中看起来不像是内存泄漏,只是临时使用了更多内存。请注意,在 GC 之后,释放的内存不会(立即)返回给操作系统,以防再次需要它。如果您的内存使用量有一个临时峰值,那么它将随着时间的推移返回给操作系统。

在某些系统中,它可能只提供给可能不接受它的操作系统,除非其他地方需要它。 (这点在 cmets 中已指出,但我不想过多介绍,以免造成混淆。)

您可以使用debug.FreeOSMemory() 强制立即返回释放的内存。

【讨论】:

    猜你喜欢
    • 2015-03-12
    • 2011-09-23
    • 2012-08-16
    • 1970-01-01
    • 2015-12-31
    • 2018-01-14
    • 1970-01-01
    • 2019-11-02
    相关资源
    最近更新 更多