2017-07-24 2 views
1

J'essaie de comprendre un problème avec l'utilisation de la mémoire dans un processus de ruby. J'ai essayé de prendre une décharge du processus ruby ​​en utilisant le module ObjectSpace pour comprendre ce qui se passe. Ce qui est déconcertant, c'est que la commande "top" de linux indique que le processus utilise 17,8 Go de mémoire virtuelle et 15 Go de mémoire résidente. Mais, la taille des décharges de tas sont seulement autour de 2.7-2.9 GB.Ruby structure de la mémoire de processus

Basé sur la documentation Ruby, la méthode Objectspace.dump_all vide le contenu du tas Ruby en tant que JSON.

Je ne suis pas capable de comprendre ce qui accapare le reste de la mémoire. Ce serait utile si quelqu'un pouvait m'aider à comprendre ce qui se passe.

Merci.

+1

[Le discours de Tenderlove au Rubyconf.au] (https://www.youtube.com/watch?v=nAEt36XNtAE) cette année pourrait être utile. – spickermann

Répondre

1

Il est probable que votre application alloue des objets qui sont ensuite nettoyés par le garbage collector. Vous pouvez vérifier cela de manière significative avec a call toGC.stat

Ruby does notrelease memoryback to the operating system. (si vous exécutez l'IRM) Par conséquent, si vous allouez 18 Go de mémoire et 15 Go d'ordures collectées, vous finirez avec vos ~ 3 Go de données de tas. Le Ruby MRI GC n'est pas un garbage collector de compactage, donc tant qu'il y a des données dans le tas, le tas ne sera pas libéré. Cela conduit à la fragmentation de la mémoire et les valeurs que vous voyez dans votre application.

+0

J'ai lu l'article et compris que Ruby libère progressivement la mémoire sur le système d'exploitation pendant un certain temps. J'ai mesuré périodiquement les emplacements de tas disponibles et il y avait constamment environ 26 millions. J'ai lu que chaque slot est de 40 octets dans une machine 64 bits. Donc, en faisant le calcul, il devrait être de 26 millions * 40 octets ~ 991 Mo. La taille de vidage du tas est de 2,9 Go et la taille de la mémoire résidente du processus est de ~ 15 Go. On dirait que la connexion me manque toujours – user2492286

+1

[Ruby ne stocke pas tout dans le tas.] (Https://stackoverflow.com/a/13639298/3784008) Les objets dont la taille dépasse le tas reçoivent de la mémoire en dehors du tas. À moins que toutes vos allocations d'objet soient <40 octets, Ruby alloue de la mémoire pour les contenir. (en utilisant malloc, en faisant abstraction de la couche de mémoire et donc en fonction du système d'exploitation) – anothermh

+0

Merci pour les précieuses informations. C'était utile de comprendre comment ruby ​​gère la mémoire. – user2492286