Ruby: Ne peut allouer de la mémoire
Je suis dans le processus de développement de Ruby on Rails application. Je suis un newbie de Ruby/Rails.
J'utilise Ruby 2.2.0 et les Rails 4.2. Quand je lance une commande comme:
rails g migration SomeMigrationName
il échoue avec le
Cannot allocate memory - fork(2) (Errno::ENOMEM)
J'utilise un Macbook Pro mi-2014 avec OS X 10.10 conseil d'administration et Vagrant/Virtualbox pour exécuter une machine virtuelle (Ubuntu 14.04) pour les Rails du développement.
Voici mon Vagabond de fichier:
Vagrant.configure(2) do |config|
config.vm.box = "ubuntu/trusty64"
config.vm.network "forwarded_port", guest: 3000, host: 3000
config.vm.synced_folder "dev", "/home/vagrant/dev"
config.vm.synced_folder "opt", "/opt"
config.vm.provider "virtualbox" do |vb|
vb.memory = "512"
end
end
J'ai lu qu'une telle erreur se produit lorsque la RAM est hors limite, mais j'utilise la même config (Vagrant fichier) pour un autre environnement de dev qui s'exécute plusieurs Python/Tornade apps, MongoDB et Redis et tout fonctionne très bien.
Dois-je augmenter la vb.valeur de la mémoire ou d'un Rubis bug?
OriginalL'auteur Nodari Lipartiya | 2015-02-02
Vous devez vous connecter pour publier un commentaire.
Quand Ruby appels
fork
l'OS pour faire une copie de l'ensemble du processus parent de l'espace d'adresse, même si la fourche est seulement appelé àexec
un autre petit processus commels
. Momentanément, votre système doit être capable d'allouer une partie de la mémoire au moins de la taille de l'Ruby processus parent avant de s'effondrer jusqu'à ce que le processus de l'enfant a réellement besoin.Si les rails sont en général très gourmands en mémoire. Alors, si quelque chose utilise
fork
, vous avez besoin de deux fois plus de mémoire.TL;DR Utilisation posix-spawn au lieu de la fourchette si vous êtes dans le contrôle du code. Donner votre VM 1024MB ou d'un peu plus d'espace de swap de prendre le relais pour la
fork
appelExemple Ruby Utilisation de la Mémoire avec
fork
Prendre un échantillon aléatoire de la VM, ce qu'on a de l'espace de swap désactivé:
Regarder la
Mem:
ligne etfree
colonne. C'est autour de votre taille limite pour un nouveau processus, dans mon cas438
MiBMon
buffers/cached
ont déjà été rincé pour ce test, afin que mafree
la mémoire est à la limite. Vous pouvez avoir besoin de prendre labuffers/cache
valeurs en compte si elles sont grosses. Linux a la capacité d'expulser rassis cache lorsque la mémoire est nécessaire par un processus.Utilisation de la mémoire
Créer un rubis processus avec une corde autour de la taille de votre mémoire libre. Il y a une surcharge pour le
ruby
processus de sorte qu'il ne va pas correspondre exactement àfree
.Alors que la chaîne de légèrement plus grand:
Ajouter un
fork
pour le ruby, réduisant ainsimb
jusqu'à ce qu'il s'exécute.Un peu plus grand, fourche processus de produire l'
ENOMEM
erreur:L'exécution d'une commande avec des backticks lance ce processus avec un
fork
a donc le même résultat:Donc là vous allez, vous aurez besoin d'environ deux fois le parent processus de la mémoire disponible sur le système de la fourche à la fourchette un nouveau processus. L'IRM Rubis s'appuie fortement sur
fork
pour la multi-modèle de processus, cela est dû à la conception de Ruby qui utilise un mondial interprète de verrouillage (GIL) qui ne permet qu'un seul thread à exécuter à la fois par ruby processus.Je crois que Python a beaucoup moins d'utilisation de
fork
en interne. Lorsque vous utilisezos.fork
en Python, la même chose se produit si:Oracle ont un article détaillé sur le problème et de parler à l'aide de la variante de
posix_spawn()
. L'article vise à Solaris, mais c'est un général POSIX Unix question s'applique à Linux (si pas la plupart des systèmes Unix).Il y a aussi un Rubis de mise en œuvre de
posix-spawn
que vous pourriez utiliser si vous êtes dans le contrôle du code. Ce module ne remplace rien dans les Rails, de sorte qu'il ne vous aidera pas ici, sauf si vous avez remplacé les appels àfork
vous-même.Errno::ENOMEM: Cannot allocate memory - file -b --mime /tmp/blabla.jpg
et cela était dû au fait que nous avons introduit extra processus de suivi (DataDog de l'agent qui a consommé 600 MO ) ...de toute façon+1
sur lefree -m
vérifier 🙂Wow, c'est ridiculement élevé pour un agent de surveillance.
OriginalL'auteur