如何在 Ruby 中测试没有 GC "loop"与"while"循环内存使用情况



我在 Ruby 版本 2.4 和 2.7 中测试了代码:

1.

GC.disable
while true
?a
end

阿拉伯数字。

GC.disable
puts ?a while true

3.

GC.disable
loop do
?a
end

4.

GC.disable
loop do
puts ?a
end

示例 1 到 4 应使用所有可用内存和交换,因为它们都在无限循环中创建字符串a,例如:

  • GC 已禁用。
  • 字符串a未冻结。

但是 #1 在执行时消耗的内存不会超过一个字节。 #2、#3 和 #4 使用尽可能多的内存。在我的系统上,它们每秒消耗大约 250 MB 左右。正如预期的那样,CPU 内核的使用率为 100%。

为什么 #1 几乎不消耗任何内存,而其他内存在很短的时间内使用所有可用的系统内存?

> Stefan在他的评论中是正确的,因为while循环不会创建一个新的范围。

还要注意puts方法的效果。每次为字符串调用它时,它都会在内存中分配一个新对象。

require "benchmark/memory"
Benchmark.memory do |x|
x.report("Test1") { puts ?a }
x.report("Test2") { ?a }
x.report("Test3") { puts ?a; puts ?a; puts ?a; puts ?a; puts ?a; puts ?a; puts ?a; puts ?a; puts ?a; puts ?a }
x.report("Test4") { ?a; ?a; ?a; ?a; ?a; ?a; ?a; ?a; ?a; ?a; }
x.compare!
end

输出:

Calculating -------------------------------------
Test1    40.000  memsize (     0.000  retained)
1.000  objects (     0.000  retained)
1.000  strings (     0.000  retained)
Test2    40.000  memsize (     0.000  retained)
1.000  objects (     0.000  retained)
1.000  strings (     0.000  retained)
Test3   400.000  memsize (     0.000  retained)
10.000  objects (     0.000  retained)
1.000  strings (     0.000  retained)
Test4    40.000  memsize (     0.000  retained)
1.000  objects (     0.000  retained)
1.000  strings (     0.000  retained)
Comparison:
Test1:         40 allocated
Test2:         40 allocated - same
Test3:        400 allocated - 10.00x more
Test4:         40 allocated - same

最新更新