Как я могу найти утечку памяти на Heroku?

У меня есть приложение Rails 3.2.8, работающее на кедрах Heroku с Ruby 1.9.3. Приложение работает нормально, когда оно запускается, но через день или около того непрерывное использование, я начинаю видеть ошибки R14 в моих журналах. Как только ошибки памяти начинаются, они никогда не уходят, даже если приложение простаивает в течение нескольких часов.

Не следует ли сборщику мусора через некоторое время очистить неиспользуемые объекты и уменьшить нагрузку на память? Кажется, это не происходит на Хереку. Как правило, использование памяти начинает закрадываться после запуска нескольких отчетов с несколькими тысячами строк данных, хотя результаты разбиваются на страницы.

Как я могу найти утечку памяти? Плагины типа bleak_house устарели или не работают в среде Heroku. Могу ли я настроить параметры GC, чтобы сделать его более агрессивным?

Ответы

Ответ 1

GC должен делать очистку и, вероятно, делает.

Вы можете заставить GC с GC.start; если многие объекты не были собраны, это будет, но я подозреваю, что это не проблема.

Возможно ли, что вы каким-то образом создаете кучу объектов и никогда не выпускаете их, сохраняя кешированные копии или что-то в этом роде?

Я не знаком с существующими инструментами, чтобы проверить это, но вы можете проверить, какие объекты существуют с помощью ObjectSpace. Например:

ObjectSpace.each_object.with_object(Hash.new(0)){|obj, h| h[obj.class] +=1 }
# => a Hash with the number of objects by class

Если вы получаете неожиданный номер для одного из ваших классов, например, у вас будет лучшее представление о том, где искать.

Ответ 2

Установите новое дополнение Relic. У этого есть куча полезных показателей, которые вы можете использовать, чтобы узнать источник утечки. Я думаю, что в целом лучше попытаться понять, какая часть кода занимает больше всего времени, и, возможно, попытайтесь ее оптимизировать, а не просто настроить GC.

Некоторые из приятных функций, которые включает в себя новая реликвия, - это, например, возможность определить источник самого длинного SQL-запроса. Я рекомендую вам попробовать.