O Python tem uma pilha / heap e como a memória é gerenciada?

91

Como as variáveis ​​e a memória são gerenciadas no Python? Ele tem uma pilha e um heap e qual algoritmo é usado para gerenciar a memória? Dado esse conhecimento, há alguma recomendação sobre gerenciamento de memória para grande número / processamento de dados?

Matt Alcock
fonte
1
Existe algum problema específico com o gerenciamento de var / memória do Python que o esteja enfrentando e que não seja descoberto de maneira trivial pela documentação do Python e / ou no Google?
Martin James

Respostas:

111

Como as variáveis ​​e a memória são gerenciadas no Python.

Automagicamente! Não, realmente, você apenas cria um objeto e a máquina virtual Python trata da memória necessária e onde ela deve ser colocada no layout de memória.

Ele tem uma pilha e um heap e qual algoritmo é usado para gerenciar a memória?

Quando estamos falando sobre CPythonele usa um heap privado para armazenar objetos. Da documentação da API CPython C :

O gerenciamento de memória em Python envolve um heap privado contendo todos os objetos e estruturas de dados Python. O gerenciamento deste heap privado é assegurado internamente pelo gerenciador de memória Python. O gerenciador de memória Python possui diferentes componentes que lidam com vários aspectos de gerenciamento de armazenamento dinâmico, como compartilhamento, segmentação, pré-alocação ou cache.

A recuperação de memória é principalmente tratada por contagem de referência . Ou seja, o Python VM mantém um diário interno de quantas referências se referem a um objeto e o coleta de lixo automaticamente quando não há mais referências a ele. Além disso, existe um mecanismo para quebrar referências circulares (que a contagem de referência não pode controlar) detectando "ilhas" de objetos inacessíveis, um pouco ao contrário dos algoritmos tradicionais de GC que tentam encontrar todos os objetos alcançáveis.

NOTA: Lembre-se de que essas informações sãoCPythonespecíficas. Outras implementações de python, comopypy,iron python,jythone outros podem ser diferentes uns dos outros e de CPython quando se trata de suas especificidades de implementação. Para entender isso melhor, pode ajudar a entender que há uma diferença entre Python, a semântica (a linguagem) e a implementação subjacente

Dado esse conhecimento, há alguma recomendação sobre gerenciamento de memória para grande número / processamento de dados?

Agora, não posso falar sobre isso, mas tenho certeza de que a NumPy (a biblioteca python mais popular para processamento de números) possui mecanismos que controlam o consumo de memória de maneira adequada.

Se você quiser saber mais sobre o Python's Internals, dê uma olhada nestes recursos:

NlightNFotis
fonte
5
Que bom que você enfatizou a distinção entre Python e CPython;)
phant0m
1
Observe que as variáveis ​​locais terão as variáveis ​​reais armazenadas no equivalente a um quadro de pilha.
Marcin
1
Python não é Java; não tem máquina virtual; tem um intérprete. Pode parecer pedante apontar isso, mas eles são dois paradigmas diferentes e a diferença tem implicações importantes sobre como o código é compilado e executado. stackoverflow.com/questions/441824/…
Apollo2020
48

Python não têm qualquer coisa.

Python é a linguagem e não especifica como exatamente as implementações devem atingir a semântica definida por Python a linguagem.

Cada implementação (CPython, PyPy, IronPython, Stackless , Jython ...) é livre para fazer suas próprias coisas!

Em C Python, todos os objetos residem no heap:

O gerenciamento de memória em Python envolve um heap privado contendo todos os objetos e estruturas de dados Python. 1

A máquina virtual CPython é baseada em pilha:

>>> 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)

Lembre-se de que isso é específico do CPython. A pilha não contém os valores reais , ela mantém referências a esses objetos.

1 : Fonte

phant0m
fonte