内存泄漏,内存中有大量SQL Logging字符串

时间:2013-11-19 09:11:04

标签: mysql ruby-on-rails activerecord memory-leaks

我的应用程序在Puma(2.4)群集模式下运行,有4名工作人员。 最初,它们总共使用不到2GB的RAM,但是在运行20小时后不断增长并最终占用7GB。

通过使用ObjectSpace,我发现字符串对象的数量增长非常快,每个工作者的对象数从〜300k到4-5百万。

然后我使用以下脚本将这些字符串分组前60个字符并执行计数:

counts = Hash.new(0) 
ObjectSpace.each_object do |o| 
  next unless (o.class == String) 
  counts[o[0,60]] += 1 
end
counts = counts.to_a.sort_by(&:last);
puts counts[-10..-1]

事实证明,这些字符串中的大部分都是来自Active Record的SQL Logging

ObjectSpace.count_objects
# result
{
     :TOTAL => 2439593,
      :FREE => 209200,
  :T_OBJECT => 65944,
   :T_CLASS => 11343,
  :T_MODULE => 2003,
   :T_FLOAT => 13,
  :T_STRING => 1821445,
  :T_REGEXP => 6570,
   :T_ARRAY => 157012,
    :T_HASH => 27477,
  :T_STRUCT => 1406,
  :T_BIGNUM => 1393,
    :T_FILE => 142,
    :T_DATA => 75081,
   :T_MATCH => 1334,
 :T_COMPLEX => 1,
:T_RATIONAL => 2809,
    :T_NODE => 51890,
  :T_ICLASS => 4530
}

# top 10 string
["PricingRule Exists: SELECT" , 74632]
[": SELECT COUNT(*) FROM `re" , 85454]
["CACHE: SELECT  `companies`" , 93045]
["PricingRule Load: SELECT  " , 114169]
["Page Load: SELECT  `pages`" , 140245]
[": SELECT COUNT(*) FROM `pa" , 182274]
["Customer Load: SELECT  `cu" , 191972]
["Company Load: SELECT  `com" , 253025]
["Page Load: SELECT `pages`." , 320267]
["DestinationCountry Load: S" , 413299]

我使用Rails 4,Ruby 2,mysql2(v0.3.13)并在警告时设置日志级别,但这些SQL字符串仍然存储并在内存中保持增加。

有没有人对此问题有任何想法或经验?如果你能提供帮助,我非常感谢。

谢谢!

1 个答案:

答案 0 :(得分:2)

这些字符串可以来自'sql.active_record'事件,原因可能是您订阅了 'sql.active_record'事件并将这些字符串保存在您的对象中,以便GB无法释放它们。

ActiveSupport::Notifications.subscribed(callback, "sql.active_record") do
end

确保在使用后取消订阅。