Какие-нибудь хорошие методы, чтобы найти утечку памяти в Ruby on Rails?

Мой проект получает утечку памяти, после развертывания его память увеличивается с 500 МБ до 1800 МБ за 10 минут.

Я перепробовал много инструментов, но ни один из них не прост в использовании.

Я использовал JProfiler, который показывает стеки вызовов, распределения памяти, который класс/метод вызывается слишком много... в виде диаграммы, очень легко читаемой и анализируемой. Мне действительно это нравится.

как это: enter image description here

а вот так:

enter image description here

Я уже нашел этот инструмент: https://github.com/tenderlove/heap-analyzer, но я не использовал.

Итак, какие-нибудь хорошие методы/инструменты, чтобы найти утечки памяти ruby /rails?

Я пробовал mini_profiler, не работает, как я ожидал.

большое спасибо!

Ответ 1

Вы также можете попробовать эти инструменты для анализа вашего приложения на широком уровне.

Вы также должны сосредоточиться на управлении памятью GC и jemalloc.

Ответ 2

Техника это как:

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

    Утечка не может быть огромной, вам просто нужно быть уверенным, что это происходит. Также сервер должен работать в режиме одного процесса (в противном случае вы можете получить бесполезный дамп из другого процесса, который мог бы не просочиться).

  2. Создайте специальное действие (что-то вроде GET/do_dump), которое будет:
require 'objspace'
ObjectSpace.dump_all(output: File.open('dump.json', 'w'))

Обратите внимание, что это тяжелая операция, которая даст огромный файл

  1. Действие, которое сделает GC.start пару раз
  2. Запустить утечку, затем метод с GC и немного подождать
  3. Возьмите свалку с действием из шага 2
  4. Проанализируйте его с помощью таких инструментов, как анализатор кучи, о которых вы упоминали, или вручную, цель состоит в том, чтобы найти висячие объекты и их пути к корням.

Несколько лет назад я решил похожую проблему, написав гем heap_dump для ruby 1.9.2 (на самом деле он очень похож на ObjectSpace.dump_all), он не совместим с современными рубинами, но применимы все общие подсказки в readme.

Также могут быть проблемы с фрагментацией памяти, вы можете попробовать использовать ruby, созданный с помощью jemalloc. Но обычно они должны появляться только после гораздо более продолжительного времени работы

PS. на всякий случай - убедитесь, что у вас нет GC.disable где-то в вашем коде

Ответ 3

Я еще не видел, чтобы они упоминались как ответ:

Подробности использования, наряду с некоторыми предлагаемыми решениями (jemalloc) подробно представлены здесь

Ответ 4

Вы можете подтвердить утечку памяти, если значение GC.stat [: heap_live_slot] постоянно увеличивается для каждого запроса.

Также вы можете пройти через это для более подробной информации - RUBY-GC

Надеюсь, это полезно