web-dev-qa-db-fra.com

détection de fuite de mémoire ruby ​​/ Ruby on Rails

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.

  • Existe-t-il de bons outils permettant de détecter les fuites de mémoire dans Ruby/rails?
  • Quels types de modèles de codage provoquent des fuites de mémoire dans Ruby?
45
Josh Moore

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.

37
Dave Nolan

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.

17
Daniel Beardsley

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

6
Jean

Vous devriez jeter un coup d'œil à Ruby-prof .

5
Vetal4eg

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.

2
Sardathrion

Passez à jruby et utilisez le Eclipse Memory Analyzer . .__ Il n'y a pas d'outil comparable pour Ruby pour le moment. 

2
kohlerm

Ces gemmes ont fonctionné pour moi:

MemoryLogic

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

Oink

Analyseur de journaux pour identifier les actions qui augmentent considérablement la taille de segment VM

0