Ruby大数组和内存

时间:2012-08-11 07:06:55

标签: ruby memory memory-management

我创建了一个大数组a,其内存增长到~500 MB:

a = []

t = Thread.new do 
  loop do
    sleep 1
    print "#{a.size} "
  end
end

5_000_000.times do
  a << [rand(36**10).to_s(36)]
end

puts "\n size is #{a.size}"
a = []

t.join

之后,我“清除”a,但分配的内存在我杀死进程之前没有改变。我需要做些什么特别的事情来删除从内存中分配给a的所有这些数据吗?

2 个答案:

答案 0 :(得分:4)

您可以致电GC.start(),但您可能不想这样做。有关Stack Overflow的讨论,请参阅示例:Ruby garbage collect。基本上,我会让垃圾收集器自行决定何时运行,除非你有令人信服的理由强迫它。

答案 1 :(得分:4)

如果我在代码的轻微修改版本上使用Ruby Garbage Collection Profiler

GC::Profiler.enable
GC::Profiler.clear

a = []
5_000_000.times do
  a << [rand(36**10).to_s(36)]
end

puts "\n size is #{a.size}"
a = []

GC::Profiler.report

我得到以下输出(在Ruby 1.9.3上)(删除了一些列和行):

GC 60 invokes.
Index    Invoke Time(sec)       Use Size(byte)     Total Size(byte)     ...
    1               0.109               131136               409200     ...
    2               0.125               192528               409200     ...
  ...
   58              33.484            199150344            260938656     ...
   59              36.000            211394640            260955024     ...

配置文件以131 136字节开头,以211 394 640字节结尾,在运行的任何地方都没有减小,我们可以假设没有垃圾收集。

如果我然后添加一行代码,将一个元素添加到数组a,放置在已经增长到500万个元素之后,然后分配一个空数组:

GC::Profiler.enable
GC::Profiler.clear

a = []
5_000_000.times do
  a << [rand(36**10).to_s(36)]
end

puts "\n size is #{a.size}"
a = []

# the only change is to add one element to the (now) empty array a
a << [rand(36**10).to_s(36)]

GC::Profiler.report

这会将探查器输出更改为(删除了一些列和行):

GC 62 invokes.
Index    Invoke Time(sec)       Use Size(byte)     Total Size(byte)     ...
    1               0.156               131376               409200     ...
    2               0.172               192792               409200     ...
  ...
   59              35.375            211187736            260955024     ...
   60              36.625            211395000            469679760     ...
   61              41.891              2280168            307832976     ...

此分析器运行现在以131 376字节开始,与上一次运行类似,增长,但结束时使用2 280 168字节,明显低于之前使用211 394 640字节结束的配置文件运行,我们可以假设在此运行期间发生了垃圾收集,这可能是由我们的新代码行触发的,该代码向a添加了一个元素。

简短的回答是否定的,您不需要做任何特殊的事情来删除分配给a的数据,但希望这能为您提供证明它的工具。

相关问题