Python a-t-il une pile / tas et comment la mémoire est-elle gérée?

91

Comment les variables et la mémoire sont-elles gérées en Python? At-il une pile et un tas et quel algorithme est utilisé pour gérer la mémoire? Compte tenu de ces connaissances, existe-t-il des recommandations sur la gestion de la mémoire pour le traitement de grands nombres / données?

Matt Alcock
la source
1
Vous voudrez peut-être lire les deux suivants: foobarnbaz.com/2012/07/08/understanding-python-variables docs.python.org/2/c-api/memory.html
user1690293
1
Y a-t-il un problème spécifique avec Python var / gestion de la mémoire avec lequel vous rencontrez un problème et qui n'est pas trivialement découvert par la documentation Python et / ou Google?
Martin James

Réponses:

111

Comment les variables et la mémoire sont-elles gérées en Python?

Automagiquement! Non, vraiment, vous créez juste un objet et la machine virtuelle Python gère la mémoire nécessaire et où elle doit être placée dans la disposition de la mémoire.

At-il une pile et un tas et quel algorithme est utilisé pour gérer la mémoire?

Quand nous en parlons, CPythonil utilise un tas privé pour stocker des objets. À partir de la documentation de l'API CPython C :

La gestion de la mémoire en Python implique un tas privé contenant tous les objets et structures de données Python. La gestion de ce tas privé est assurée en interne par le gestionnaire de mémoire Python. Le gestionnaire de mémoire Python a différents composants qui traitent de divers aspects de la gestion du stockage dynamique, comme le partage, la segmentation, la préallocation ou la mise en cache.

La récupération de la mémoire est principalement gérée par le comptage de références . Autrement dit, la machine virtuelle Python tient un journal interne du nombre de références faisant référence à un objet et le ramasse automatiquement lorsqu'il n'y a plus de références qui s'y réfèrent. De plus, il existe un mécanisme pour casser les références circulaires (que le comptage de références ne peut pas gérer) en détectant des "îlots" d'objets inaccessibles, un peu à l'inverse des algorithmes GC traditionnels qui tentent de trouver tous les objets accessibles.

REMARQUE: veuillez garder à l'esprit que ces informations sontCPythonspécifiques. D' autres implémentations de python, commepypy,iron python,jythonetautres peuvent différer les unsautres et de CPython en ce qui concerne leurs spécificités de miseœuvre. Pour mieux comprendre cela, il peut être utile de comprendre qu'il existe une différence entre Python, la sémantique (le langage) et l'implémentation sous-jacente

Compte tenu de ces connaissances, existe-t-il des recommandations sur la gestion de la mémoire pour le traitement de grands nombres / données?

Maintenant, je ne peux pas en parler, mais je suis sûr que NumPy (la bibliothèque python la plus populaire pour le calcul des nombres) dispose de mécanismes qui gèrent la consommation de mémoire avec élégance.

Si vous souhaitez en savoir plus sur les composants internes de Python, consultez ces ressources:

NlightNFotis
la source
5
Bien à vous, vous insistez sur la distinction entre Python et CPython;)
phant0m
1
Notez que les variables locales auront les variables réelles stockées dans l'équivalent d'un cadre de pile.
Marcin
1
Python n'est pas Java; il n'a pas de machine virtuelle; il a un interprète. Cela peut sembler pédant de le souligner, mais ce sont deux paradigmes différents et la différence a des implications importantes sur la façon dont le code est compilé et exécuté. stackoverflow.com/questions/441824/…
Apollo2020
48

Python n'a rien de tel.

Python est le langage et ne spécifie pas exactement comment les implémentations doivent atteindre la sémantique définie par Python le langage.

Chaque implémentation (CPython, PyPy, IronPython, Stackless , Jython ...) est libre de faire ses propres choses!

En C Python, tous les objets vivent sur le tas:

La gestion de la mémoire en Python implique un tas privé contenant tous les objets et structures de données Python. 1

La machine virtuelle CPython est basée sur la pile:

>>> def g():
    x = 1
    y = 2
    return f(x, y)

>>> import dis
>>> dis.dis(g)
  2           0 LOAD_CONST           1 (1) # Push 1 onto the stack
              3 STORE_FAST           0 (x) # Stores top of stack into local var x

  3           6 LOAD_CONST           2 (2) # Push 2 onto stack
              9 STORE_FAST           1 (y) # Store TOS into local var y

  4          12 LOAD_GLOBAL          0 (f) # Push f onto stack
             15 LOAD_FAST            0 (x) # Push x onto stack
             18 LOAD_FAST            1 (y) # Push y onto stack
             21 CALL_FUNCTION        2     # Execute function with 2 
                                           # f's return value is pushed on stack
             24 RETURN_VALUE               # Return TOS to caller (result of f)

Gardez à l'esprit que cela est spécifique à CPython. La pile ne contient cependant pas les valeurs réelles , elle conserve les références à ces objets.

1 : Source

phant0m
la source