Ruby / Ruby en rieles de detección de fugas de memoria
-
03-07-2019 - |
Pregunta
Escribí una pequeña aplicación web con Ruby on Rails, su propósito principal es cargar, almacenar y mostrar resultados de archivos xml (los archivos pueden tener hasta varios MB). Después de correr por aproximadamente 2 meses, noté que el proceso mestizo estaba usando aproximadamente 4GB de memoria. Hice algunas investigaciones sobre la depuración de fugas de memoria ruby ??y no pude encontrar mucho. Así que tengo dos preguntas.
- ¿Existen buenas herramientas que puedan usarse para encontrar fugas de memoria en Ruby / rails?
- ¿Qué tipo de patrones de codificación causan pérdidas de memoria en ruby?
Solución
Algunos consejos para encontrar fugas de memoria en Rails:
- use Bleak House plugin
- implementar monitoreo de Scout específicamente el generador de perfiles de uso de memoria
-
implementa monitoreo de FiveRuns - pruebe con otro registrador de uso de memoria simple
El primero es una exploración gráfica del uso de memoria por objetos en el ObjectSpace.
Los dos últimos te ayudarán a identificar patrones de uso específicos que están inflando el uso de la memoria, y puedes trabajar desde allí.
En cuanto a los patrones de codificación específicos, por experiencia, hay que ver todo lo que se relaciona con el archivo io, el procesamiento de imágenes, el trabajo con cadenas masivas y similares.
Verificaría si está utilizando la biblioteca XML más adecuada: se sabe que ReXML es lento y se cree que tiene fugas (¡no tengo ninguna prueba de eso!). También verifique si puede memoize operaciones costosas.
Otros consejos
Un método súper simple para registrar el uso de la memoria después o antes de cada solicitud (solo para 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
Es posible que desee cargar un script / consola y probar primero la declaración para asegurarse de que funciona en su caja.
puts 'RAM USAGE: ' + `pmap #{Process.pid} | tail -1`[10,40].strip
Luego, solo supervisa la parte superior, cuando una solicitud haga saltar el uso de la memoria, ve a revisar los registros. Esto, por supuesto, solo ayudará si tiene una pérdida de memoria que se produce en saltos grandes, no en pequeños incrementos.
La pérdida de memoria es un problema en la implementación actual de ruby.
http://whytheluckystiff.net/articles/theFullyUpturnedBin.html ¿Por qué el sitio web de theuckystiff ya no existe pero puede encontrar el artículo original aquí: http: // viewsourcecode. org / why / hacking / theFullyUpturnedBin.html
para una respuesta más específica sobre problemas con procesos ruby ??de larga ejecución, consulte http: // zdavatz .wordpress.com / 2007/07/18 / heap-fragmentation-in-a-long-running-ruby-process /
tal vez podría darle una oportunidad al pasajero (mod_rails) http: // nubyonrails .com / articles / ask-your-doctor-about-mod_rails
Deberías echar un vistazo a ruby-prof .
Cambie a jruby y use el Eclipse Memory Analyzer . No hay una herramienta comparable para Ruby en este momento.
Ahora, puede ejecutar lo siguiente para obtener la memoria en un formato que R pueda leer. Estoy asumiendo que su línea de registro se ve así:
1234567890 RAM USAGE: 27456K
Ejecuta esto (o modifica a suite):
$ grep 'RAM USAGE' fubar.log | awk '{print s " " $1 " " $4; s++}' | sed 's/K//g' > mem.log
Entonces puedes ejecutar esto:
#!/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
y obtén un buen gráfico.
Estas gemas funcionaron para mí:
Agrega la identificación de proceso y el uso de memoria en tus registros de rieles, excelente para rastrear las fugas de memoria
Analice el analizador para identificar acciones que aumenten significativamente el tamaño del montón de VM