Why does Ruby release memory only occasionally?

Depending on how I create the string, Ruby will free up memory for the OS, otherwise it will not. The first test code will take about 235 MB

size = 2**22
string = '!@#$%^&*()-+~`a1234567890abcdefghijklmnopqrstuvwxyz' * size
puts 'Sleeping...'
sleep(5)
string = nil
GC.start
puts 'Just sitting here..'
gets.chomp

After the call, the GC.startmemory used by the test will be reduced to a few kilobytes. But if I do the same tests with string = (0...size).map { (65 + rand(26)).chr }.join, the memory will shoot up to 250 MB, and the memory usage will actually increase to 290 MB after the call GC.start.

EDIT: I am using Ruby 1.9.3-p448 because the project I am working on requires this. Although I will test it on Ruby 2.2 and come back with the results.

EDIT 2: Running test code in Ruby 2.1 (Ruby 2.2 was not available in RVM, and I just wanted to run the test quickly) gave similar results. Memory has not yet decreased to a reasonable state. He moved from 234MB BGCs (to GC.start) to the 197MB AGC. Note: the memory sizes were different because I ran them on another machine, but the specific sizes do not matter only the relative increase and decrease (or does not decrease).

+4
source share
1 answer

Ruby MRI does not free memory back to the OS.

Here's what I see with Ruby MRI 2.2 on OSX 10.10, using a typical one ps -o rss:

  • Highlighting a row using *uses ~ 220 MB.

  • map ~ 340 .

GC.start RSS. , , .

, map :

  • (0...size).map{ '' } ~ 300 .

, - :

  • * , .. RSS .

  • map ~ 40M .

  • (0...size).map{ '' } ~ 40M .

, Ruby map . , Ruby NoMemoryException, , .

+2

Source: https://habr.com/ru/post/1569072/


All Articles