我的应用程序在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字符串仍然存储并继续增加内存.
有没有人对这个问题有任何想法或经验?如果你能提供帮助,我非常感谢.
谢谢!
最佳答案 这些字符串可以来自’sql.active_record’事件,原因可能是您订阅了
‘sql.active_record’事件并将这些字符串保存在您的对象中,以便GB无法释放它们.
ActiveSupport::Notifications.subscribed(callback, "sql.active_record") do
end
确保在使用后取消订阅.