如何在 Ruby 中测试 "loop" 与 "while" 没有 GC 的循环内存使用情况
How to test "loop" vs "while" loop memory usage without GC in Ruby
我在 Ruby 版本 2.4 和 2.7 中测试了代码:
1.
GC.disable
while true
?a
end
2.
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
我在 Ruby 版本 2.4 和 2.7 中测试了代码:
1.
GC.disable
while true
?a
end
2.
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