我创建了一个大数组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
的所有这些数据吗?
答案 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的数据,但希望这能为您提供证明它的工具。