为什么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,并且在调用GC后内存使用量实际上会增加到290MB .开始.

编辑:我正在使用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的使用保持不变.

值得注意的是,地图使用了大量的RAM:

>(0 … size).map {”}使用~300MB.

当我循环你的例子时,会出现一些有趣的东西:

>使用*分配大字符串继续使用相同的RAM,即RSS没有太大变化.
>使用map分配大字符串每个循环增加~40M.
>只做(0 …大小).map {”}每循环增长约40M.

这告诉我Ruby映射可能有与RAM相关的问题.这不是一个问题,因为Ruby没有提出NoMemoryException,但似乎是对RAM的非最佳使用.

点赞