Question

Bonjour,

Nous avons récemment mis à jour une application Rails 3.0.4 (3.0.5 sur le serveur en ligne devel). La plupart des changements de 2.3.10 à 3.0.4 étaient obsolètes en raison de plugins ou obsolètes et des pierres précieuses, et étaient résoluble avec une relative facilité. Mais une chose me fait devenir fou:

Chaque requête web unique, en mode développement, provoque le processus du serveur d'allouer environ 50-60 Mo plus de mémoire qu'auparavant. Cette mémoire est pas libéré après la demande, au moins pas tout. Après 10-20 demandes, tous les cas Ruby consommé sur 500 Mo de RAM , tandis que nos Rails précédents 2.3.10 instances étaient rarement supérieures à 200 Mo.

Il est donc impossible d'exécuter nos essais 1300, parce que les 4 Go de la machine devel de RAM est remplie avant la fin des essais. Il ne se produit que dans le mode de développement avec cache_classes = false. Si je passe cache_classes true, les instances Rails consommera environ 200 Mo de mémoire, puis y rester. Cependant, lors des essais, même avec cache_classes = true, utilisation de la mémoire se développera.

I interrogé ObjectSpace et a trouvé que, avec chaque requête, 3500 Proc nouveau, jusqu'à 50'000 nouvelles cordes et 3000 nouveaux hachages et groupes sont créés et non libéré. Ces chaînes (lorsque déversé) contenait tout mon code source, y compris les plugins et les pierres précieuses, la documentation, les commentaires du code source et les noms de chemin. (Pourquoi?)

Pour trouver la cause de cela, voici ce que j'ai essayé: (. Après chaque changement, je les applications avec martelé ab -n 50)

  1. Je créé un frais Rails 3 application avec une seule ressource et contrôleur et SQLite3 DB. Utilisation de la mémoire a commencé à 60 Mo et est resté en dessous de 80 Mo .
  2. J'ai changé 'sqlite3' à 'pg' et a souligné les nouveaux rails 3 app à mon DB Postgres existant. Utilisation de la mémoire a commencé à 110 Mo et ne pousse pas au-delà de 130Mo . (Question Côté: Pourquoi l'utilisation de pierres précieuses Postgres beaucoup plus de mémoire que la gemme SQLite3)
  3. Je copiais sur mon Gemfile et Gemfile.lock de l'application Rails3 cassé à l'application des os nus et RAN paquet install . Pas de changement , la mémoire est resté à environ 115 Mo, peu importe combien de demandes ont été faites.
  4. J'ai créé un vide "def FooController; def foo; rendre: text => end 'foo'; end" dans l'application Rails3 cassé. Utilisation de la mémoire a augmenté plus lentement, mais encore jamais cessé de croître après les demandes .
  5. J'ai supprimé toutes les routes sauf pour la route FooController. Pas de changement .
  6. J'ai désactivé toutes les gemmes, sauf pour ce qui suit: pg, rails, aasm, will_paginate, geokit-rails3, koala, omniauth, paperclip. Pas de changement .
  7. J'ai désactivé tous les before_filter et after_filter dans ApplicationController et tous les non essentiels include dans environment.rb. J'ai aussi synced boot.rb, environment.rb et application.rb avec mes os nus Rails 3 application, sauf pour cinq observateurs relativement simples, les fichiers dans autoloading / lib et filter_parameters. Pas de changement . Chaque nouvelle demande toujours consommé un 10-50 supplémentaire Mo de RAM.

Si vous avez une idée de ce qui va mal ici, et où la fuite de mémoire pourrait être, je serais vraiment reconnaissant d'aide. Je courais Rails 3.0.4 sur Mac OS X Snow Leopard, Rails 3.0.5 sur Debian Lenny et

Merci!

Plus près:

J'ai enlevé tous les plug-in, chaque bijou, chaque extension et tout ce que je ne me suis pas écrire personnellement, de sorte que ma demande est essentiellement nue. Surtout, j'ai enlevé ces plug-ins. acts_as_list, acts_as_tree, asset_packager, forgot_password, fudge_form, fudge_scaffold, paperclippolymorph, query_trace, rails_upgrade, repeated_auto_complete-0.1.0, role_requirement, to_select, validates_url, and ym4r_gm

Maintenant ma demande - que le FooController fonctionne toujours! - commence avec 65MB et ne va jamais au-delà de 75 Mo de RAM, même après le marteler avec ab -n 1000 -c1 (1000 requêtes HTTP à / foo en utilisant ApacheBench). Malheureusement, sans les plug-ins, c'est aussi le seul URI qui fonctionne à tous.

Après quelques recherches, il semble qu'une combinaison entre l'authentification Restful et agit comme machine d'état (AASM)plugins provoque la fuite de mémoire. Voir aussi https://github.com/Satish/restful-authentication/issues#issue / 11 . Je ne sais pas encore pourquoi, et faire juste « INCLUDE AASM » dans mon projet bare-bones ne provoque pas la croissance de l'utilisation de la RAM par elle-même.

Je vais étudier plus.

Culprit trouvés

Il est AASM. Dans Rails 3, il semble fuir les instances d'objet AASM :: xxx. voir

Deuxième trouvé coupable

Il y avait une autre fuite de mémoire dans rspec. Cela fait mes tests presque insupportablement lent, même après le retrait AASM, parce que deux parallèles l'exécution des tâches rspec (en utilisant https: // GitHub. com / grosser / parallel_tests ) a pris presque 3 Go de mémoire à la fin. Voir https://github.com/rspec/rspec-core/issues/# question / 321 .

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top