【发布时间】:2020-01-07 15:56:18
【问题描述】:
我在 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 几乎不消耗任何内存,而其他人在很短的时间内使用所有可用的系统内存?
【问题讨论】:
-
我注意到的事情没有特别的顺序:在我的系统上,代码 2 也消耗了所有可用内存。通过
ruby --dump=insns <filename>检查指令序列时,似乎Ruby 优化了代码1 中的文字。它还表明loop创建了一个块(即新的变量范围),而while没有。添加# frozen_string_literal: true消除了所有 4 的内存消耗。 -
糟糕,2 也属于 3 和 4 的类别(内核正在将页面写入 zram,没有注意到),现在已编辑。谢谢...