我最近推出了一个新的Rails应用程序,它在开发模式下运行良好。在启动之后,我一直在体验正在使用的内存在不断增加:


更新了:当这个屏幕转储(下面的一个)从新文物被拿走时。我计划每小时重新启动一次web dyno (每两个web dynos中就有一个)。因此,它没有达到500 of的崩溃级别,它实际上得到了一个sig锯模式。然而,这个问题根本没有得到解决,只有一些症状。如你所见,早上不那么忙,但下午更忙。我在11.30上传了一个很小的细节,它不可能影响到问题,即使它出现在统计中。
还可以注意到,尽管图表显示了AVG内存,但最小内存仍在不断增加。即使在图形中出现暂时下降的情况下,最小内存仍然保持不变或增加。最小的记忆永远不会减少!
该应用程序(没有dyno重新启动)会增加内存,直到达到Heroku的最高水平,程序崩溃时执行过期-类型的错误。
我不是一个伟大的程序员,但我已经做了一些应用程序之前,没有这种类型的问题。
执行故障排除
答:我原以为问题在before_filter in application_controller (Will variables in application controller cause a memory leak in Rails?)中,但那不是问题所在。
我安装了oink,但没有给出任何结果。它创建了一个oink.log,但在运行"heroku运行oink -m log/oink.log“时没有给出任何结果,不管是什么阈值。
我尝试过bleak_house,但它被废弃了,无法安装
我搜索并阅读了这个主题中的大多数文章,但我一点也不聪明。
我很想测试memprof,但我无法安装它(我有Ruby1.9x,也不知道如何将其降级到1.8x)
我的问题:
Q1。我真正想知道的是每个请求增加的变量的名称,或者至少哪个控制器使用的内存最多。
Q2。下面的代码会增加控制器的内存吗?
related_feed_categories = []
@gift.tags.each do |tag|
tag.category_connections.each do |cc|
related_feed_categories << cc.category_from_feed
end
end(对不起,由于某些原因,不会重新格式化代码以便于阅读)。
之后我需要用"related_feed_categories = nil“来”关闭“related_feed_categories,还是垃圾收集器处理这个问题?
Q3。我要找的主要东西是什么?现在我根本不能缩小范围。我不知道应该深入研究代码的哪一部分,也不知道该查找什么。
Q4。万一我真的解决不了这个问题。有没有任何在线咨询服务,我可以发送我的代码,并让他们找到问题?
谢谢!
更新了。在收到评论后,它可能与会话有关。这是代码的一部分,我猜可能是坏的:
# Create sessions for last generation
friend_data_arr = [@generator.age, @generator.price_low, @generator.price_high]
friend_positive_tags_arr = []
friend_negative_tags_arr = []
friend_positive_tags_arr << @positive_tags
friend_negative_tags_arr << @negative_tags
session["last_generator"] = [friend_data_arr, friend_positive_tags_arr, friend_negative_tags_arr]
# Clean variables
friend_data_arr = nil
friend_positive_tags_arr = nil
friend_negative_tags_arr = nil它用于generator#show控制器中。当一些礼物已经通过我的礼物生成引擎生成时,我将输入保存在一个会话中(以防他们想在稍后阶段使用该信息)。我从不杀死或终止这些会话,所以这可能会导致内存增加。
再次更新:我删除了这段代码,但内存仍然增加,所以我想这部分不是它,而是类似的代码可能会导致错误?
发布于 2012-09-27 14:13:30
这不太可能是我们的related_feed_categories引起的。
你用了很多文件吗?
您保存会话数据多长时间?看起来你有一个电子商务网站,你在会话中保存对象吗?
基本上,我认为这是文件或会话,或者服务器崩溃时临时刷新数据的增加(memcache ?)。
在半夜,我想你的顾客少了。你能在高峰时间发同样的记忆图吗?
它可能与这个问题有关:Memory grows indefinitely in an empty Rails app
更新:
Rails不将所有数据存储在客户端。我不记得默认的存储,但除非您选择cookie::store,rails只发送像session_id这样的数据。
对于会话,ActiveRecord::SessionStore似乎是性能方面的最佳选择。您不应该在会话中保存大型对象或机密数据。更多关于会话的内容:http://guides.rubyonrails.org/security.html#what-are-sessions
在2.9部分中,您有一个销毁会话的解释,这些会话在一段时间内未使用。
与其将对象存储在会话中,我建议您存储给搜索结果的url。您甚至可以将其存储在数据库中,为您的客户节省很少的研究,并且/或默认情况下加载最后一次使用的负载。
但在这一阶段,我们仍不完全确定会议是否是罪魁祸首。为了确定,您可以在测试服务器上尝试使用到期的会话对应用程序进行压力测试。因此,基本上,您创建了大量的会话,可能20分钟后rails就必须抑制它们。如果你发现内存消耗有什么不同,它会缩小范围。
第一种情况:会话到期时内存显著下降,您知道这是与会话相关的。
第二种情况:内存以更快的速度增长,但在会话到期时不要下降,您知道它是与用户相关的,而不是与会话相关的。
第三种情况:没有变化(内存通常会增加),所以您知道这不取决于用户的数量。但我不知道是什么导致了这一切。
当我说压力测试的时候,我指的是大量的压力测试,而不是压力测试。您需要的会话数量取决于您的平均用户数。如果你有50个用户,在你的应用程序崩溃之前,20-30个会话可能是非常重要的。因此,如果您手动配置了它们,则配置一个更高的过期时间限制。我们只是在寻找记忆构成上的差异。
更新2 :
所以这很可能是内存泄漏。因此,使用对象空间,它有一个count_objects方法,它将显示当前使用的所有对象。它应该缩小范围。当内存已经增加了很多的时候使用它。
否则,您就有了bleak_house,它是一个能够找到内存泄漏的宝石,用于内存泄漏的红宝石工具不如java工具有效,但值得一试。
Github:house
更新3:
这可能是一个解释,这不是真正的内存泄漏,但它会增加内存:http://www.tricksonrails.com/2010/06/avoid-memory-leaks-in-ruby-rails-code-and-protect-against-denial-of-service/
简而言之,在重新启动红宝石之前,符号一直保存在内存中。因此,如果符号是用随机名称创建的,内存就会增加,直到应用程序崩溃。这种情况不会发生在String,‘t中。
有点旧,但对于ruby1.9.x有效,请尝试如下: Symbol.all_symbols.size
更新4:
所以,你的符号可能是记忆泄漏。现在我们还得找出它发生的地方。使用Symbol.all_symbols。它给了你名单。我想您可以将其存储在某个地方,并与新数组进行区分,以查看添加了什么。
它可能是i18n,也可能是以隐式方式生成的其他东西,比如i18n。但是不管怎么说,这可能是在用名字中的随机数据生成符号。然后这些符号就再也不用了。
发布于 2012-09-27 13:44:32
假设category_from_feed返回一个字符串(或者一个符号),300 is的增长幅度是不太可能的。您可以通过对以下内容进行分析来粗略地得出这一点:
4_000_000.times {related_feed_categories << "Loooooooooooooong string" }这个片段将使内存使用量增加约110 up。
我会查看读取文件的DB连接或方法,然后不关闭它。我可以看到它与提要相关,这可能意味着您可能正在使用XML。这也是一个起点。
将此作为答案发布,因为这在评论中看起来很糟糕:/
https://stackoverflow.com/questions/12578344
复制相似问题