Ruby/Ruby on Rails: обнаружение утечек памяти
-
03-07-2019 - |
Вопрос
Я написал небольшое веб-приложение, использующее Ruby on Rails, его основная цель — загружать, хранить и отображать результаты из файлов xml (размер файлов может достигать нескольких МБ).Проработав около 2 месяцев, я заметил, что процесс дворняги использует около 4 ГБ памяти.Я провел небольшое исследование по устранению утечек памяти Ruby и не смог найти многого.Итак, у меня есть два вопроса.
- Есть ли хорошие инструменты для поиска утечек памяти в Ruby/rails?
- Какие шаблоны кодирования вызывают утечки памяти в Ruby?
Решение
Несколько советов по поиску утечек памяти в Rails:
- использовать Мрачный дом плагин
- осуществлять Скаутский мониторинг в частности, профилировщик использования памяти
осуществлять Мониторинг FiveRuns- попробуй другой простой регистратор использования памяти
Первый — это графическое исследование использования памяти объектами в ObjectSpace.
Последние два помогут вам определить конкретные модели использования, которые увеличивают использование памяти, и вы сможете работать исходя из этого.
Что касается конкретных шаблонов кодирования, по опыту вам придется наблюдать за всем, что касается файлового ввода-вывода, обработки изображений, работы с массивными строками и тому подобного.
Я бы проверил, используете ли вы наиболее подходящую библиотеку XML - известно, что ReXML медленный и негерметичный (у меня нет доказательств этого!).Также проверьте, можете ли вы запоминать дорогостоящие операции.
Другие советы
Очень простой метод регистрации использования памяти после или перед каждым запросом (только для Linux).
#Put this in applictation_controller.rb
before_filter :log_ram # or use after_filter
def log_ram
logger.warn 'RAM USAGE: ' + `pmap #{Process.pid} | tail -1`[10,40].strip
end
Возможно, вы захотите загрузить скрипт/консоль и сначала опробовать оператор, чтобы убедиться, что он работает на вашем компьютере.
puts 'RAM USAGE: ' + `pmap #{Process.pid} | tail -1`[10,40].strip
Затем просто следите за верхом: когда запрос приводит к скачку использования памяти, проверьте журналы.Это, конечно, поможет только в том случае, если у вас утечка памяти происходит большими скачками, а не крошечными приращениями.
Утечка памяти является проблемой в текущей реализации Ruby, и хорошее место для начала —http://whytheluckystiff.net/articles/theFullyUpturnedBin.html Веб-сайтWhytheluckystiff больше не существует, но оригинал статьи можно найти здесь: http://viewsourcecode.org/why/hacking/theFullyUpturnedBin.html
более конкретный ответ о проблемах с длительными процессами Ruby см.http://zdavatz.wordpress.com/2007/07/18/heap-fragmentation-in-a-long-running-ruby-process/
возможно, вы могли бы попробовать пассажира (mod_rails) http://nubyonrails.com/articles/ask-your-doctor-about-mod_rails
Вам следует взглянуть на руби-проф.
Переключитесь на jruby и используйте Анализатор памяти Eclipse.На данный момент для Ruby не существует аналогичного инструмента.
Теперь вы можете запустить следующее, чтобы получить память в формате, который может читать R.Я предполагаю, что ваша строка журнала выглядит так:
1234567890 RAM USAGE: 27456K
Запустите это (или измените на пакет):
$ grep 'RAM USAGE' fubar.log | awk '{print s " " $1 " " $4; s++}' | sed 's/K//g' > mem.log
Затем вы можете запустить это:
#!/bin/sh
rm -f mem.png
R --vanilla --no-save --slave <<RSCRIPT
lst <- read.table("mem.log")
attach(lst)
m = memory / 1024.0
summary(m)
png(filename="mem.png", width=1024)
plot(date, m, type='l', main="Memory usage", xlab="time", ylab="memory")
RSCRIPT
и получить красивый график.
Эти драгоценные камни помогли мне:
Добавляет идентификатор процесса и использование памяти в журналы рельсов, что отлично подходит для отслеживания утечек памяти.
Анализатор журналов для выявления действий, которые значительно увеличивают размер кучи виртуальной машины.