如何在Heroku上找到内存泄漏?

17

我有一个运行在Heroku Cedar上,使用Ruby 1.9.3的Rails 3.2.8应用程序。当应用程序启动时,它可以正常运行,但是在连续使用一天左右后,我的日志开始出现R14错误。一旦内存错误发生,即使应用程序闲置了数小时,错误也不会消失。

垃圾回收器难道不应该在一段时间后清理掉未使用的对象并减少内存负载吗?似乎在Heroku上这种情况并没有发生。通常情况下,内存使用率会在运行一些包含几千行数据的报告后开始逐渐增加,尽管结果是分页显示的。

如何找到内存泄漏?像bleak_house这样的插件已经过时或无法在Heroku环境中正常运行。我能否调整GC设置以使其更具攻击性?

2个回答

7

垃圾回收器应该进行清理工作,而且可能已经这样做了。

你可以使用GC.start强制进行垃圾回收;如果许多对象没有被收集,那么这将会发生,但我怀疑这不是问题的原因。

有可能你创建了一堆对象并且从未释放它们,通过保留缓存副本或其他方式?

我不熟悉现有的检查工具,但你可以使用ObjectSpace来检查存在哪些对象。例如:

ObjectSpace.each_object.with_object(Hash.new(0)){|obj, h| h[obj.class] +=1 }
# => a Hash with the number of objects by class

如果您在某个课程中得到了意外的数字,您会更清楚应该在哪里寻找答案。

-1

安装New Relic插件。它有许多有用的指标,可以帮助您找出泄漏的源头。我认为,通常最好的做法是尝试查看哪个代码部分执行时间最长,然后尝试优化它,而不是直接调整GC。

New Relic包括的一些不错的功能之一是能够精确定位最长运行的SQL查询的源头。我鼓励您尝试一下。


2
我已经安装了 New Relic,但它没有给我所需的详细级别。 - Marty M.
1
New Relic对于解决内存问题没有太大的帮助。它可以提供一些GC信息,但无法准确定位问题。 - 2mia
同意。NewRelic 对很多事情都有帮助,但调试内存泄漏不是其中之一。 - bloudermilk
我不同意。NewRelic可以显示Ruby堆。Heroku内存图表是应用程序内存。如果您的C语言本地宝石有内存泄漏,那么它将出现在Heroku中,但不会出现在NewRelic中。如果您正在缓存或未释放对象,则会在NewRelic中显示。因此,NewRelic可能有助于诊断内存问题的位置。我们有一个应用程序,其中Heroku显示稳定的内存增长到5 GB,但NewRelic显示Ruby堆增长(最高可达3 MB)并缩小。这告诉我我的问题可能与分配器有关,我们应该使用jemalloc。 - Marlin Pierce

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接