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

sou*_*sou 6 ruby memory release

作为标题,我有一个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)
Run Code Online (Sandbox Code Playgroud)

OK,我想事情闹,我不明白,为什么GC.stat[:heap_used]仍是大我做了之后$big_var=nilGC.start

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    
Run Code Online (Sandbox Code Playgroud)

另外,我使用Ruby 2.1和CentOS 6.4

Aru*_*hit 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}"
Run Code Online (Sandbox Code Playgroud)

输出

[shreyas@arup_ruby (master)]$ ruby a.rb
memory size: 40
memory size: 11636312
memory size: 40
[shreyas@arup_ruby (master)]$
Run Code Online (Sandbox Code Playgroud)

看方法:memsize_of

  • 我认为 memsize_of 只是 big_var 现在引用的内存大小。但它之前引用的大内存仍然被Ruby持有,没有释放。 (2认同)