根据我生成字符串的方式,Ruby会将内存释放到操作系统或者它不会。第一个测试代码将占用大约235MB
size = 2**22
string = '!@#$%^&*()-+~`a1234567890abcdefghijklmnopqrstuvwxyz' * size
puts 'Sleeping...'
sleep(5)
string = nil
GC.start
puts 'Just sitting here..'
gets.chomp
调用GC.start
后,测试使用的内存将缩减回几千字节。但是,如果我使用string = (0...size).map { (65 + rand(26)).chr }.join
运行相同的测试,则在调用GC.start
后,内存将高达250MB,内存使用量实际上会增加到290MB。
编辑:我使用Ruby 1.9.3-p448作为我正在进行的项目需要它。虽然我会在Ruby 2.2上测试它并返回结果。
编辑2:在Ruby 2.1中运行测试代码(Ruby 2.2在RVM中不可用,我只是想快速运行测试)给出了类似的结果。记忆仍然没有降到合理的状态。它从234MB BGC(在GC.start之前)到197MB AGC。注意:内存大小不同,因为我在不同的机器上运行它,但具体的大小不仅仅是相对增加和减少(或非减少)。
答案 0 :(得分:2)
Ruby MRI不会将内存释放回操作系统。
这是我在OSX 10.10上使用Ruby MRI 2.2看到的,使用典型的ps -o rss
:
使用*
分配大字符串使用~220MB。
使用map
分配大字符串使用~340MB。
在我的系统上,GC.start
对RSS没有任何作用。换句话说,我看到RAM的使用保持不变。
值得注意的是,map
使用了大量的RAM:
(0...size).map{ '' }
使用~300MB。当我循环你的例子时,会出现一些有趣的东西:
使用*
分配大字符串继续使用相同的RAM,即RSS没有太大变化。
使用map
分配大字符串每个循环增加约40M。
只需(0...size).map{ '' }
每循环增加约40M。
这告诉我Ruby map
可能有与RAM相关的问题。这不是一个问题,因为Ruby没有提出NoMemoryException,但似乎是对RAM的非最佳使用。