运行以下代码块会导致整个过程消耗越来越多的内存:
require 'redis'
def rss ; `ps -o rss= -p #{Process.pid}`.chomp.to_i ; end
def gc_and_print_rss
GC.start(full_mark: true, immediate_sweep: true)
rss.to_s.gsub(/(\d)(?=(\d{3})+(\..*)?$)/,'\1,') + " kilobytes"
end
str = ('dummystring' * 1000).freeze
list_name = 'test'.freeze
r = Redis.new
r.del(list_name)
100.times do
r.pipelined do
10000.times do
r.lpush(list_name, str)
end
end
10000.times do
r.brpop(list_name)
end
something = gc_and_print_rss
puts something
end
输出为:
61,288 kilobytes
82,708 kilobytes
83,640 kilobytes
83,812 kilobytes
92,228 kilobytes
93,516 kilobytes
99,848 kilobytes
99,868 kilobytes
99,872 kilobytes
99,872 kilobytes
99,876 kilobytes (5 times)
100,528 kilobytes (9 times)
100,532 kilobytes (9 times)
100,544 kilobytes
101,036 kilobytes
101,036 kilobytes
101,036 kilobytes
我唯一的猜测是gc_and_print_rss
函数正在将字符串初始化为hval,当初始化足够的这些字符串时,ruby会从操作系统请求另一页内存。但这引出了一个问题,如何在ruby(任何非平凡的事情)中编写循环而不会在内存中爬行直到进程终止?
在macOS和Ubuntu上测试。