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

时间:2016-08-05 04:25:11

标签: google-app-engine go memory-leaks

我看到了这个Python问题:App Engine Deferred: Tracking Down Memory Leaks

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

  

在为384个请求提供服务后,超过128 MB的软私有内存限制(128 MB)

...

  

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

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

在查看应用程序后,我无法看到任何明显的泄漏位置(例如,未封闭的缓冲区等)......等等,无论它是什么,都必须是一个非常小但可能是常见的错误。

因为这是在GAE上运行的,所以我不能在本地很容易地对它进行概要分析,因为我知道它是运行时环境。 可能有人建议如何继续并确保记忆正确回收吗? - 我是Go的新手,但到目前为止我一直很喜欢使用它。

2 个答案:

答案 0 :(得分:1)

检查您的应用是否确实存在内存泄漏的一种可能方法是临时升级实例类并检查内存使用模式(在Instances页面的开发者控制台中选择Memory Usage视图对于相应的模块版本。)

如果模式最终平稳并且实例不再重新启动,那么实际上您的实例类太低了。完成:))

如果使用模式不断增长(速度与应用程序的活动成比例),那么确实存在内存泄漏。在此练习中,如果您设法将图形增长区域与应用程序的某些活动相关联,可能也可以缩小搜索范围。

即使存在泄漏,使用更高的实例类也会增加实例重启之间的时间,甚至可能使它们可容忍(例如,与动态管理的实例的自动关闭相比) 。如果您感兴趣的话,这将允许将内存泄漏调查放在次要位置并专注于更紧迫的问题。可以将这种重启视为实例刷新/自清洁“功能”:)

答案 1 :(得分:1)

作为起点,您可以尝试pprof.WriteHeapProfile。它将写入任何Writer,包括http.ResponseWriter,因此您可以编写一个视图来检查某些身份验证并为您提供堆配置文件。令人烦恼的是,它实际上是跟踪分配,而不是在GC之后分配的保留。所以从某种意义上说,它告诉你什么是RAM饥饿,但没有具体针对泄漏。

标准expvar包可以公开一些JSON,包括memstats,它告诉您有关特定分配大小(example)的GC和数量分配和释放。如果存在泄漏,您可以使用allocs - frees来了解它是否是随着时间的推移而增长的大型分配或小分配,但这不是非常细粒度的。

最后,有a function to dump the current state of the heap,但我不确定它是否适用于GAE,它似乎很少使用。

请注意,为了保持GC工作,Go过程增长到实际实时数据的两倍,作为正常稳态操作的一部分。 (GC之前的确切百分比取决于runtime.GOGC,人们有时会增加以节省收集器工作以换取使用更多内存。)(非常古老的)线程建议App Engine processes regulate GC like any other,尽管他们可以调整无论如何,如果你慢慢分配(对你有好处),你应该期望缓慢的过程增长;只是在每个收集周期后,使用量应该再次下降。