一尘不染

跟踪Google App Engine Golang应用程序中的内存泄漏?

go

我看到了这个Python问题:推迟了AppEngine:跟踪内存泄漏

…同样,我遇到了这个可怕的错误:

总共为384个请求提供服务后,超出了128 MB的软私有内存限制

处理此请求后,发现处理此请求的进程使用了​​过多的内存并被终止。这很可能导致新流程用于您的应用程序的下一个请求。如果您经常看到此消息,则可能是应用程序内存泄漏。

根据另一个问题,可能是“实例类”太小而无法运行此应用程序,但是在增加它之前,我想确定一下。

在检查完应用程序后,我看不到任何可能的泄漏点(例如,未关闭的缓冲区等)…,因此无论它是什么,它肯定是一个很小但可能是常见的错误。

因为它是在GAE上运行的,所以据我所知,那是运行时环境,因此我无法真正真正地在本地对其进行概要分析。
可能有人会对如何进行操作并确保正确回收内存提出建议。 —我是Go的新手,但到目前为止,我一直很喜欢使用它。


阅读 202

收藏
2020-07-02

共1个答案

一尘不染

首先,您可以尝试pprof.WriteHeapProfile。它将写入任何一个Writer,包括一个http.ResponseWriter,因此您可以编写一个视图以检查某些auth并为您提供堆配置文件。令人讨厌的是,它实际上是在跟踪
分配 ,而不是跟踪GC之后 剩余的 分配。因此,从某种意义上讲,它是在告诉您需要多少RAM,但并没有专门针对泄漏。

标准expvar包可以公开一些包含memstats的JSON,它告诉您关于GC以及特定分配大小的allocs
frees的数量(示例)。如果有泄漏,您可以使用allocs-
frees了解随着时间的推移增长的是大型分配还是小型分配,但这并不是很精细。

最后,有一个函数可以转储堆的当前状态,但是我不确定它是否可以在GAE中使用,并且似乎很少使用。

请注意,为保持GC正常运行,Go进程的增长是其 正常 实时数据的两倍, 是正常稳态操作的一部分
。(在GC依赖之前runtime.GOGC,它增长的确切百分比,人们有时会增加以节省收集器的工作,以换取使用更多的内存。)一个(很旧的)线程建议App
Engine进程像其他任何进程一样对GC进行调节
,尽管他们可能对此进行了调整2011。无论如何,如果分配缓慢(对您有好处!),您应该 期望
流程增长缓慢;只是用法应该在每个收集周期之后再次下降。

2020-07-02