首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >查找Ruby中内存泄漏的原因

查找Ruby中内存泄漏的原因
EN

Stack Overflow用户
提问于 2013-12-05 04:57:17
回答 4查看 15.5K关注 0票数 59

我在我的Rails代码中发现了一个内存泄漏-也就是说,我已经找到了泄漏的代码,但不知道它为什么泄漏。我已经将其简化为不需要Rails的测试用例:

代码语言:javascript
复制
require 'csspool'
require 'ruby-mass'

def report
    puts 'Memory ' + `ps ax -o pid,rss | grep -E "^[[:space:]]*#{$$}"`.strip.split.map(&:to_i)[1].to_s + 'KB'
    Mass.print
end

report

# note I do not store the return value here
CSSPool::CSS::Document.parse(File.new('/home/jason/big.css'))

ObjectSpace.garbage_collect
sleep 1

report

ruby-mass应该可以让我看到内存中的所有对象。CSSPool是一个基于racc的CSS解析器。/home/jason/big.css为a 1.5MB CSS file

这将输出以下内容:

代码语言:javascript
复制
Memory 9264KB

==================================================
 Objects within [] namespace
==================================================
  String: 7261
  RubyVM::InstructionSequence: 1151
  Array: 562
  Class: 313
  Regexp: 181
  Proc: 111
  Encoding: 99
  Gem::StubSpecification: 66
  Gem::StubSpecification::StubLine: 60
  Gem::Version: 60
  Module: 31
  Hash: 29
  Gem::Requirement: 25
  RubyVM::Env: 11
  Gem::Specification: 8
  Float: 7
  Gem::Dependency: 7
  Range: 4
  Bignum: 3
  IO: 3
  Mutex: 3
  Time: 3
  Object: 2
  ARGF.class: 1
  Binding: 1
  Complex: 1
  Data: 1
  Gem::PathSupport: 1
  IOError: 1
  MatchData: 1
  Monitor: 1
  NoMemoryError: 1
  Process::Status: 1
  Random: 1
  RubyVM: 1
  SystemStackError: 1
  Thread: 1
  ThreadGroup: 1
  fatal: 1
==================================================

Memory 258860KB

==================================================
 Objects within [] namespace
==================================================
  String: 7456
  RubyVM::InstructionSequence: 1151
  Array: 564
  Class: 313
  Regexp: 181
  Proc: 113
  Encoding: 99
  Gem::StubSpecification: 66
  Gem::StubSpecification::StubLine: 60
  Gem::Version: 60
  Module: 31
  Hash: 30
  Gem::Requirement: 25
  RubyVM::Env: 13
  Gem::Specification: 8
  Float: 7
  Gem::Dependency: 7
  Range: 4
  Bignum: 3
  IO: 3
  Mutex: 3
  Time: 3
  Object: 2
  ARGF.class: 1
  Binding: 1
  Complex: 1
  Data: 1
  Gem::PathSupport: 1
  IOError: 1
  MatchData: 1
  Monitor: 1
  NoMemoryError: 1
  Process::Status: 1
  Random: 1
  RubyVM: 1
  SystemStackError: 1
  Thread: 1
  ThreadGroup: 1
  fatal: 1
==================================================

你可以看到memory way up。一些计数器会上升,但不存在特定于CSSPool的对象。我使用ruby- objects的"index“方法来检查具有如下引用的对象:

代码语言:javascript
复制
Mass.index.each do |k,v|
    v.each do |id|
        refs = Mass.references(Mass[id])
        puts refs if !refs.empty?
    end
end

但是再说一次,这并没有给我任何与CSSPool相关的东西,只有gem信息之类的。

我也尝试过输出"GC.stat"...

代码语言:javascript
复制
puts GC.stat
CSSPool::CSS::Document.parse(File.new('/home/jason/big.css'))
ObjectSpace.garbage_collect
sleep 1
puts GC.stat

结果:

代码语言:javascript
复制
{:count=>4, :heap_used=>126, :heap_length=>138, :heap_increment=>12, :heap_live_num=>50924, :heap_free_num=>24595, :heap_final_num=>0, :total_allocated_object=>86030, :total_freed_object=>35106}
{:count=>16, :heap_used=>6039, :heap_length=>12933, :heap_increment=>3841, :heap_live_num=>13369, :heap_free_num=>2443302, :heap_final_num=>0, :total_allocated_object=>3771675, :total_freed_object=>3758306}

据我所知,如果一个对象没有被引用,并且发生了垃圾回收,那么这个对象应该从内存中清除。但这似乎不是这里正在发生的事情。

我也读过关于C级内存泄漏的文章,因为CSSPool使用使用C代码的Racc,所以我认为这是一种可能性。我已经通过Valgrind运行了我的代码:

代码语言:javascript
复制
valgrind --partial-loads-ok=yes --undef-value-errors=no --leak-check=full --fullpath-after= ruby leak.rb 2> valgrind.txt

结果是here。我不确定这是否证实了C级的泄漏,因为我也读到过Ruby使用内存做Valgrind不理解的事情。

使用的版本:

  • Ruby 2.0.0-p247 (这是我的Rails应用程序运行的代码)
  • Ruby 1.9.3-p392-ref (用于使用Ubuntu6.4和Ubuntu13.10

中的Ubuntu4.0.0进行测试

EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20385767

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档