J'ai écrit une petite application Web à l'aide de Ruby on Rails. Son objectif principal est de télécharger, stocker et afficher les résultats de xml (les fichiers peuvent contenir plusieurs Mo). Après avoir fonctionné pendant environ 2 mois, j'ai remarqué que le processus bâtard utilisait environ 4 Go de mémoire. J'ai fait des recherches sur le débogage des fuites de mémoire Ruby et je n'ai pas trouvé grand chose. J'ai donc deux questions.
Quelques conseils pour détecter les fuites de mémoire dans Rails:
La première est une exploration graphique de l'utilisation de la mémoire par les objets dans l'ObjectSpace.
Les deux derniers vous aideront à identifier des modèles d'utilisation spécifiques qui gonflent l'utilisation de la mémoire, et vous pouvez travailler à partir de là.
En ce qui concerne les modèles de codage spécifiques, vous devez, par expérience, regarder tout ce qui concerne les fichiers io, le traitement des images, le travail avec des chaînes volumineuses, etc.
Je vérifierais si vous utilisez la bibliothèque XML la plus appropriée - ReXML est connu pour sa lenteur et son étanchéité (je n’en ai aucune preuve!). Vérifiez également si vous pouvez mémoize opérations coûteuses.
Une méthode très simple pour consigner l'utilisation de la mémoire avant ou après chaque demande (uniquement pour 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
Vous voudrez peut-être charger le script/la console et essayer d’abord la déclaration pour vous assurer qu’elle fonctionne sur votre boîte.
puts 'RAM USAGE: ' + `pmap #{Process.pid} | tail -1`[10,40].strip
Ensuite, surveillez simplement en haut, lorsqu'une requête accélère l'utilisation de votre mémoire, consultez les journaux. Bien entendu, cela n’aidera que si une fuite de mémoire survient lors de sauts importants et non par incréments minimes.
Une fuite de mémoire est un problème dans l’implémentation actuelle de Ruby. Un bon point de départ pour commencer est http://whytheluckystiff.net/articles/theFullyUpturnedBin.html Le site Whytheluckystiff n'existe plus, mais vous pouvez trouver l'article original ici: http://viewsourcecode.org/why/hacking/theFullyUpturnedBin.html
pour une réponse plus précise sur les problèmes liés aux processus Ruby longs, voir http://zdavatz.wordpress.com/2007/07/18/heap-fragmentation-in-a-long-running-Ruby-process/
peut-être pourriez-vous essayer passager (mod_Rails) http://nubyonrails.com/articles/ask-your-doctor-about-mod_Rails
Vous devriez jeter un coup d'œil à Ruby-prof .
Maintenant, vous pouvez exécuter ce qui suit pour obtenir la mémoire dans un format lisible par R. Je suppose que votre ligne de journal ressemble à:
1234567890 RAM USAGE: 27456K
Exécutez ceci (ou modifiez à la suite):
$ grep 'RAM USAGE' fubar.log | awk '{print s " " $1 " " $4; s++}' | sed 's/K//g' > mem.log
Ensuite, vous pouvez exécuter ceci:
#!/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
et obtenez un graphique de Nice.
Passez à jruby et utilisez le Eclipse Memory Analyzer . .__ Il n'y a pas d'outil comparable pour Ruby pour le moment.
Ces gemmes ont fonctionné pour moi:
Ajoute l'identifiant de processus et l'utilisation de la mémoire dans vos journaux Rails, ce qui est idéal pour localiser les fuites de mémoire
Analyseur de journaux pour identifier les actions qui augmentent considérablement la taille de segment VM