如何强制Ruby释放内存给操作系统

7
作为标题所述,我有一个处理大量数据的Ruby程序。该程序占用了所有内存,并在其中调用系统命令hostname时出现了错误。

Cannot allocate memory - hostname

我尝试过GC.start但没有起作用。

那么我该如何强制Ruby释放未使用的内存呢?

好的,这是其他人的测试代码,最后的错误显示big_var已被回收,但内存仍未释放。

require "weakref"
def report
  puts "#{param}:\t\t Memory " + `ps ax -o pid,rss | grep -E "^[[:space:]]*#{$$}"`
      .strip.split.map(&:to_i)[1].to_s + 'KB'
end
big_var = ""
#big_var = WeakRef.new(big_var)

report
big_var = 1_000_000.times.map(&:to_s)
report

big_var = WeakRef.new(big_var)

GC.start

sleep 1
report

p big_var.length

#Memory 7508KB
#Memory 61516KB
#Memory 53700KB
#test.rb:20:in `<main>': Invalid Reference - probably recycled (WeakRef::RefError)

好的,我尝试了下面的事情,但不明白为什么在执行$big_var=nilGC.start后,GC.stat[:heap_used]仍然如此之大。

puts GC.stat[:heap_used]
$big_var = []
  5000000.times { |i|
    $big_var << i.to_s
  }
puts GC.stat[:heap_used]
$big_var = nil
puts GC.stat[:heap_used]
GC.start
puts GC.stat[:heap_used]

#70
#12286
#12286
#9847    

此外,我使用Ruby 2.1和CentOS 6.4。

http://ruby-doc.org/stdlib-2.1.2/libdoc/weakref/rdoc/WeakRef.html - Arup Rakshit
展示给我们代码。 - peter
我已经放置了测试代码,谢谢关注~~ - sou
简而言之:你做不到。 - cremno
谢谢大家。现在我知道我无法实现那件事情。 - sou
也许你可以修补Ruby,这应该不难。 - Pavel Evstigneev
1个回答

2

我可以看到垃圾回收是由WeakRef类完成的,正如文档所述。这是我尝试证明这一点的方法:

require 'objspace'
require "weakref"

big_var = ""
puts "memory size: #{ObjectSpace.memsize_of big_var}"

big_var = 1_000_000.times.map(&:to_s)
puts "memory size: #{ObjectSpace.memsize_of big_var}"

big_var = WeakRef.new(big_var)
GC.start

puts "memory size: #{ObjectSpace.memsize_of big_var}"

输出

[shreyas@arup_ruby (master)]$ ruby a.rb
memory size: 40
memory size: 11636312
memory size: 40
[shreyas@arup_ruby (master)]$

Look at the method : memsize_of.


是的,即使将big_var设置为nil,我仍然可以获得相同的输出。但是内存仍然没有被释放~~~ - sou
2
我认为memsize_of只是big_var现在引用的内存大小。但是之前它所引用的大内存仍由Ruby持有,未被释放。 - sou
@sou 好的,可能吧... 我不确定 :/ - Arup Rakshit

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接