为什么Ruby有时只释放内存?
根据我如何生成字符串,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
运行相同的测试,内存将高达250MB,内存使用实际上将增加到290MB GC.start
。
编辑:我正在使用Ruby 1.9.3-p448作为我正在研究的项目需要它。 虽然我将在Ruby 2.2上测试它并返回结果。
编辑2:在Ruby 2.1中运行测试代码(RVM中没有Ruby 2.2,我只是想快速运行测试)给出了类似的结果。 记忆仍然没有降到合理的状态。 它从234MB BGC(在GC.start之前)到197MB AGC。 注意:内存大小不同,因为我在不同的计算机上运行它,但具体大小与相对增加和减少(或非减少)无关。
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的非最佳使用。