Ruby大数组和内存

我创建了一个大数组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所有这些数据吗?

如果我在代码的轻微修改版本上使用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的数据,但希望这能为您提供certificate它的工具。

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

    Interesting Posts