2015-03-03 59 views
3

作爲標題,我有一個ruby程序處理大量的數據。該計劃把所有的內存和有系統命令hostname在裏面, 的主叫和錯誤發生如何強制Ruby釋放內存到操作系統

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) 

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  

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

+0

http://ruby-doc.org/stdlib-2.1.2/libdoc/weakref/rdoc/WeakRef.html – 2015-03-03 08:04:20

+0

它不起作用。 – sou 2015-03-03 08:25:44

+0

告訴我們代碼sou – peter 2015-03-03 08:33:45

回答

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}" 

輸出

[[email protected]_ruby (master)]$ ruby a.rb 
memory size: 40 
memory size: 11636312 
memory size: 40 
[[email protected]_ruby (master)]$ 

看看這個方法:memsize_of

+0

是的,我可以得到相同的輸出,即使只是設置big_var爲零。但內存仍然沒有發佈~~~ – sou 2015-03-03 09:14:39

+0

我認爲memsize_of只是big_var現在引用的內存大小。但是之前引用的大內存仍然由Ruby保存,而沒有發佈。 – sou 2015-03-03 09:18:02

+0

@sou好的可能是..我不確定:/ – 2015-03-03 09:18:44