Chr*_*fer 11 memory ruby-on-rails heroku
我最近推出了一个新的Ruby on Rails应用程序,它在开发模式下运行良好.在发布之后,我一直在体验正在使用的内存不断增加:
更新:当从New Relic获取此屏幕转储(下面的那个)时.我已经安排了每小时重启web dyno(两个web dynos中的一个).因此,它没有达到500Mb的崩溃水平,它实际上得到了一些sig锯模式.但问题根本没有得到解决,只有一些症状.你可以看到早上不是那么忙,但下午更忙.我在11.30上传了一个小细节,即使它在统计数据中显示也不会影响问题.
还可以注意到,即使图形显示AVG存储器,也是MIN存储器继续增加.即使图形似乎在图表中暂时下降,最小内存保持不变或增加.MIN记忆永不减少!
该应用程序将(没有dyno重新启动)内存增加,直到它达到Heroku的最高级别,并且应用程序崩溃执行过期类型的错误.
我不是一个优秀的程序员,但我之前已经制作了一些应用程序而没有这类问题.
执行故障排除
答:我认为问题在于application_controller中的before_filter(应用程序控制器中的变量会导致Rails中的内存泄漏吗?)但这不是问题.
B.我安装了oink但它没有给出任何结果(根本).它创建了一个oink.log,但是当我运行"heroku run oink -m log/oink.log"时,无论什么阈值都没有给出任何结果.
C.我尝试过bleak_house但它已被弃用,无法安装
D.我用谷歌搜索并阅读了主题中的大多数文章,但我不是更明智的.
E.我很想测试memprof但是我无法安装它(我有Ruby 1.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
Run Code Online (Sandbox Code Playgroud)
(抱歉,因为某些原因,所以不会重新格式化代码以便于阅读).
我之后是否需要使用"related_feed_categories = nil""kill""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
Run Code Online (Sandbox Code Playgroud)
它用在生成器#show controller中.当通过我的礼物生成引擎生成一些礼物时,我将输入保存在会话中(如果他们想在稍后阶段使用该信息).我永远不会杀死或过期这些会话,以防万一这会导致内存增加.
再次更新:我删除了这段代码,但内存仍在增加,所以我猜这部分不是它,但类似的代码可能会导致错误?
我们的related_feed_categories不太可能引发这种情况.
你使用了很多文件吗?
您保留会话数据多长时间?看起来你有一个电子商务网站,你在会话中保留对象吗?
基本上,我认为是服务器崩溃时刷新的临时数据文件,会话或增加(memcache?).
在半夜,我想你的客户较少.你可以在高峰时段张贴相同的记忆图表吗?
它可能与此问题有关:内存在空Rails应用程序中无限增长
更新:
Rails不会在客户端存储所有数据.我不记得默认存储,除非你选择cookie :: store,rails只发送session_id这样的数据.
它们几乎没有关于会话的指导,ActiveRecord :: SessionStore似乎是性能目的的最佳选择.而且你不应该在会话中保留大对象或秘密数据.更多关于会议的内容:http://guides.rubyonrails.org/security.html#what-are-sessions
在2.9部分中,您有一个解释来销毁在一段时间内未使用的会话.
我建议你存储提供搜索结果的网址,而不是在会话中存储对象.您甚至可以将其存储在数据库中,从而可以为您的客户节省一些研究,和/或默认情况下加载最后使用的数据.
但在这个阶段,我们仍然不完全确定会议是罪魁祸首.为了确保这一点,您可以尝试使用测试服务器,对应用程序进行压力测试,并使会话过期.所以基本上,你创建了大量的会话,也许20分钟后rails必须压制它们.如果你发现内存消耗有任何差异,它会缩小范围.
第一种情况:当会话到期时内存显着下降,你知道这是与会话相关的.
第二种情况:内存以更快的速度增加,但在会话到期时不会丢失,您知道它与用户相关,但与会话无关.
第三种情况:没有变化(通常会增加内存),所以你知道它不依赖于用户数量.但我不知道是什么原因引起的.
当我说压力测试时,我的意思是大量的会议,而不是真正的压力测试.您需要的会话数取决于您的平均用户数.如果你有50个用户,那么在你的应用程序崩溃之前,20到30个会话可能是非常重要的.因此,如果您手动拥有它们,请配置更高的过期时间限制.我们只是在寻找内存消耗的差异.
更新2:
所以这很可能是内存泄漏.所以使用对象空间,它有一个count_objects方法,它将显示当前使用的所有对象.它应该缩小范围.当内存已经增加很多时使用它.
否则,你有bleak_house,一个能够找到内存泄漏的gem,仍然用于内存泄漏的ruby工具不如java那么高效,但它值得一试.
Github:https://github.com/evan/bleak_house
更新3:
这可能是一个解释,这不是真正的内存泄漏,但它增长了记忆:http: //www.tricksonrails.com/2010/06/avoid-memory-leaks-in-ruby-rails-code-and-protect-针对-拒绝服务/
简而言之,符号将保留在内存中,直到重启ruby为止.因此,如果使用随机名称创建符号,则内存将增长,直到您的应用程序崩溃.使用字符串不会发生这种情况.
有点旧,但对ruby 1.9.x有效试试这个:Symbol.all_symbols.size
更新4:
所以,你的符号可能是内存泄漏.现在我们仍然需要找到它发生的位置.使用Symbol.all_symbols.它给你列表.我想你可以将它存储在某处,并使用新数组进行差异,以便查看添加的内容.
它可能是i18n,或者它可能是像i18n这样隐式生成的其他东西.但无论如何,这可能会在名称中生成带有随机数据的符号.然后这些符号再也不会被使用了.
假设category_from_feed
返回一个字符串(或者可能是一个符号),则 300MB 的增加量是不太可能的。您可以通过分析来粗略地得出这一点:
4_000_000.times {related_feed_categories << "Loooooooooooooong string" }
Run Code Online (Sandbox Code Playgroud)
此代码片段将使内存使用量增加约 110MB。
我会查看读取文件然后不关闭它的数据库连接或方法。我可以看到它与提要相关,这可能意味着您可能正在使用 XML。这也可以作为一个起点。
将此作为答案发布,因为这在评论中看起来很糟糕:/