ruby/ruby on rails 内存泄漏检测
Posted
技术标签:
【中文标题】ruby/ruby on rails 内存泄漏检测【英文标题】:ruby/ruby on rails memory leak detection 【发布时间】:2010-09-14 17:58:34 【问题描述】:我使用 ruby on rails 编写了一个小型 Web 应用程序,它的主要目的是上传、存储和显示来自 xml(文件最多几 MB)文件的结果。运行大约 2 个月后,我注意到 mongrel 进程使用了大约 4GB 的内存。我对调试 ruby 内存泄漏进行了一些研究,但找不到太多。所以我有两个问题。
有没有什么好的工具可以用来查找 Ruby/rails 中的内存泄漏? 什么类型的编码模式会导致 ruby 中的内存泄漏?【问题讨论】:
【参考方案1】:在 Rails 中查找内存泄漏的一些技巧:
使用Bleak House插件 具体实现Scout monitoring 内存使用分析器 尝试另一个simple memory usage logger第一个是对 ObjectSpace 中对象的内存使用情况的图形探索。
最后两个将帮助您识别导致内存使用量膨胀的特定使用模式,您可以从那里开始工作。
至于特定的编码模式,根据经验,您必须观察处理文件 io、图像处理、处理大量字符串等的任何内容。
我会检查您是否使用了最合适的 XML 库 - 众所周知,ReXML 很慢并且被认为是泄漏的(我没有证据!)。还要检查你是否可以memoize 昂贵的操作。
【讨论】:
Bleak House 的帖子是 2007 年的,今天这仍然是一个有效的选择吗?【参考方案2】:在每个请求之后或之前记录内存使用情况的超级简单方法(仅适用于 Linux)。
#Put this in applictation_controller.rb
before_filter :log_ram # or use after_filter
def log_ram
logger.warn 'RAM USAGE: ' + `pmap #Process.pid | tail -1`[10,40].strip
end
您可能需要加载脚本/控制台并首先尝试该语句以确保它适用于您的机器。
puts 'RAM USAGE: ' + `pmap #Process.pid | tail -1`[10,40].strip
然后就是监控top,当一个请求让你的内存使用量跳跃时,去查看日志。当然,这只有在内存泄漏发生在大跳跃而不是微小增量时才会有所帮助。
【讨论】:
log_ram 方法从何而来? 在 osx 上你可以使用 vmmap #Process.pid【参考方案3】:内存泄漏是当前 ruby 实现中的一个问题,一个很好的起点是
http://whytheluckystiff.net/articles/theFullyUpturnedBin.htmlWhytheluckystiff 网站已不存在,但您可以在此处找到原始文章:https://viewsourcecode.org/why/hacking/theFullyUpturnedBin.html
有关长时间运行的 ruby 进程问题的更具体答案,请参阅 https://just.do/2007/07/18/heap-fragmentation-in-a-long-running-ruby-process/
也许您可以尝试一下乘客 (mod_rails) https://web.archive.org/web/20130901072209/http://nubyonrails.com/articles/ask-your-doctor-about-mod_rails
【讨论】:
【参考方案4】:你应该看看ruby-prof。
【讨论】:
【参考方案5】:切换到 jruby 并使用 Eclipse Memory Analyzer。 目前没有可比的 Ruby 工具。
【讨论】:
【参考方案6】:现在,您可以运行以下命令以 R 可以读取的格式获取内存。我假设您的日志行如下所示:
1234567890 RAM USAGE: 27456K
运行这个(或修改为套件):
$ grep 'RAM USAGE' fubar.log | awk 'print s " " $1 " " $4; s++' | sed 's/K//g' > mem.log
然后你可以运行这个:
#!/bin/sh
rm -f mem.png
R --vanilla --no-save --slave <<RSCRIPT
lst <- read.table("mem.log")
attach(lst)
m = memory / 1024.0
summary(m)
png(filename="mem.png", width=1024)
plot(date, m, type='l', main="Memory usage", xlab="time", ylab="memory")
RSCRIPT
并得到一个漂亮的图表。
【讨论】:
【参考方案7】:这些宝石对我有用:
MemoryLogic
在 Rails 日志中添加进程 ID 和内存使用情况,非常适合跟踪内存泄漏
Oink
日志解析器可识别显着增加 VM 堆大小的操作
【讨论】:
以上是关于ruby/ruby on rails 内存泄漏检测的主要内容,如果未能解决你的问题,请参考以下文章