Утечка памяти в ruby - PullRequest
       113

Утечка памяти в ruby

0 голосов
/ 09 апреля 2020

У меня есть такой код в irb:

2.6.3 :001 > a = []; 100000000000.times do a.push([1]) end
^CTraceback (most recent call last):
        3: from (irb):1
        2: from (irb):1:in `times'
        1: from (irb):1:in `block in irb_binding'
IRB::Abort (abort then interrupt!)
2.6.3 :002 > a.clear
 => [] 
2.6.3 :003 > GC.start
 => nil 
2.6.3 :004 > a.size
 => 0 
2.6.3 :005 > exit

Мой график памяти:

enter image description here

Таким образом, память полностью освобождается только на выходе.

Как полностью освободить память перед выходом из приложения?

1 Ответ

2 голосов
/ 09 апреля 2020

Работа в соответствии с назначением

Это утечка, если и только если память не возвращается в систему после выхода Ruby. Поскольку описываемое вами поведение не является справедливым, можно сказать, что ваш интерпретатор работает, как задумано.

Подробнее о том, как сборщик мусора Ruby работает на высоком уровне, см. Ниже. и почему ваше построение массивов так интенсивно использует память.

Нет утечки памяти

Это не утечка; Вот как работает Ruby сборщик мусора ! По сути, это сборщик мусора с меткой-зачисткой, с новой поддержкой сжатия. На высоком уровне Ruby выделяет память для объектов, все еще находящихся в области, и, как правило, не освобождает выделение, пока все ссылки go не попадают в область.

Ruby сборка мусора не хорошо документированы за пределами исходного кода, а реализация немного сложнее, чем я описал выше. Кроме того, реализация сборки мусора может варьироваться от выпуска к выпуску, а также от разных интерпретаторов (например, J Ruby и MRI)! Тем не менее, достаточно понять, что вы видите.

По сути, 100000000000.times do a.push([1]) end доставит sh элемент в массив a 100 миллионов раз. Пока a находится в области, память не будет собирать мусор. Даже если вы вручную запустите процедуры сборки мусора после того, как a выйдет из области видимости, Ruby может или не может освободить память, если система не находится под давлением памяти.

Я бы не стал не беспокойтесь об этом, если у вас нет очень долгоживущих процессов, которым нужно хранить миллионы записей в активной памяти. Если вы это сделаете, специальный кэш или база данных (например, memcached, Redis) могут быть более эффективными.

...