【问题标题】:How can I find a memory leak on Heroku?如何在 Heroku 上找到内存泄漏?
【发布时间】:2012-10-30 00:00:51
【问题描述】:

我有一个运行在 Heroku Cedar 上的 Rails 3.2.8 应用程序和 Ruby 1.9.3。该应用程序在启动时运行良好,但在连续使用一天左右后,我开始在我的日志中看到 R14 错误。一旦内存错误开始,它们就永远不会消失,即使应用程序空闲了几个小时。

垃圾收集器是否应该在一段时间后清理未使用的对象并减少内存负载? Heroku 上似乎没有发生这种情况。通常,在运行一些包含数千行数据的报告后,内存使用量会开始攀升,尽管结果是分页的。

如何找到内存泄漏?像 bleak_house 这样的插件已经过时或者不能在 Heroku 环境中很好地运行。我可以调整 GC 设置以使其更具侵略性吗?

【问题讨论】:

    标签: ruby-on-rails ruby heroku ruby-on-rails-3.2 ruby-1.9.3


    【解决方案1】:

    安装 New Relic 插件。它有许多有用的指标,您可以使用它们来找出泄漏的来源。我认为尝试查看代码的哪一部分执行时间最长并可能尝试优化它通常是一个更好的主意,而不是直接调整 GC。

    例如,New Relic 包含的一些不错的功能是能够查明运行时间最长的 SQL 查询的来源。我鼓励你试一试。

    【讨论】:

    • 我安装了新的遗物,但它没有给我所需的详细程度
    • newrelic 对解决内存问题毫无用处。它确实为您提供了一些 GC 信息,但没有什么可以指出问题。
    • 同意。 NewRelic 对很多事情都有帮助,但调试内存泄漏不是其中之一。
    • 我不同意。 NewRelic 可以显示 ruby​​ 堆。 heroku 内存图表是应用程序内存。如果您从用 C 编写的本机 gem 中出现内存泄漏,那么它将出现在 heroku 中,但不会出现在 NewRelic 中。如果您正在缓存或不释放对象,它将显示在 NewRelic 中。因此,NewRelic 可用于诊断内存问题所在。我们有一个应用程序,其中 heroku 显示稳定的内存增长到 5 GB,但 NewRelic 显示 ruby​​ 堆增长(高达 3 MB)和缩小。这告诉我我的问题可能出在分配器上,我们应该使用 jemalloc。
    【解决方案2】:

    GC 应该进行清理,并且可能会这样做。

    你可以用GC.start强制GC;如果没有收集很多对象,这将是,但我怀疑这不是问题。

    您是否有可能通过保留缓存副本或其他方式以某种方式创建一堆对象并且从不释放它们?

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

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

    例如,如果您的某个课程的号码出现意外数字,您会更好地了解在哪里寻找。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-09-25
      • 2011-01-09
      • 2013-04-04
      • 1970-01-01
      • 2018-04-07
      相关资源
      最近更新 更多