Python有堆栈吗?内存是如何管理的?

125

Python中的变量和内存是如何管理的?它是否有堆栈和堆,并使用哪种算法来管理内存?鉴于这些知识,对于大量数据处理,有没有关于内存管理的建议?


1
你可能想阅读以下两篇文章:http://foobarnbaz.com/2012/07/08/understanding-python-variables/ http://docs.python.org/2/c-api/memory.html - user1690293
1
你是否遇到了Python变量/内存管理方面的特定问题,而这些问题并不是通过Python文档和/或谷歌轻松发现的? - Martin James
2个回答

141
{我}将翻译以下内容:关于Python中变量和内存的管理。
自动魔法!不,实际上,您只需创建一个对象,Python虚拟机会处理所需的内存以及它应该放置在内存布局中的位置。
当我们谈论CPython时,它使用一个私有堆来存储对象。 来自CPython C API文档
Python中的内存管理涉及包含所有Python对象和数据结构的私有堆。 Python内存管理器确保对此私有堆的管理。 Python内存管理器具有处理各种动态存储管理方面(如共享、分段、预分配或缓存)的不同组件。
记忆回收主要由引用计数处理。也就是说,Python虚拟机会记录一个对象被多少个引用所引用的内部日志,并在没有更多引用指向它时自动进行垃圾回收。此外,还有一种机制来打破循环引用(引用计数无法处理),通过检测不可访问的对象“孤岛”,有点类似于传统GC算法的反向方式,试图找到所有可达的对象。 注意:请记住,这些信息是特定于CPython的。其他Python实现,如pypyiron pythonjython等,在实现细节上可能与彼此和CPython有所不同。为了更好地理解这一点,需要理解Python语义(语言)和底层实现之间的区别

基于这些知识,是否有关于大量数据/数据处理的内存管理建议?

现在我不能详细谈论这个问题,但我确信NumPy(用于数字计算的最流行的Python库)具有优雅处理内存消耗的机制。
如果您想了解更多关于Python内部的信息,请查看以下资源:

7
感谢您强调Python与CPython的区别。 - phant0m
3
请注意,本地变量将存储在类似于堆栈帧的等效位置中。 - Marcin
3
Python不是Java,它没有虚拟机,而是有一种解释器。指出这一点可能显得学究一些,但它们是两种不同的编程范式,这种差异对代码编译和运行方式有重要影响。 - Apollo2020
@Apollo2020 Cpython解释器本身包含了自己的虚拟机实现,因此它是一个虚拟机。你说得对,它不是JVM,但它仍然是一个虚拟机。在运行时,所有的Python代码都会首先被“编译”成Cpython VM本地的字节码,这就是为什么存在.pyc文件,它们是为Cpython VM保存在文件中的字节码,以避免需要重新编译。 - ThisGuyCantEven
NumPy只是本地LAPack(即OpenBLAS、MKL)的包装器,它具有自己的内存管理,不在CPython之外。这是100%的要求,因为Python VM的引用计数操作不是原子操作,因此不是线程安全的(这就是GIL存在的原因)。如果NumPy在底层使用了Cpython的内存管理,它将非常缓慢,因为它将受到GIL的限制,无法并行化数值操作。 - ThisGuyCantEven
@Apollo2020,另外,Python不是运行时或解释器,它是一种语言。解释器只是将您的Python代码解析为AST,然后使用该AST为正在使用的运行时发出字节码的应用程序(.pyc用于CPython,可能是.CLASS用于Jython,因为.CLASS文件是JVM的字节码)。即使Pypy最终也会发出字节码以在LLVM上运行(还使用另一种中间表示形式)。 - ThisGuyCantEven

67

Python没有任何这样的东西。

Python是一种编程语言,它不规定实现必须如何实现由Python语言定义的语义。

每个实现(CPython、PyPy、IronPython、Stackless、Jython...)都可以做自己的事情!

CPython中,所有对象都存放在堆上:

Python中的内存管理涉及一个包含所有Python对象和数据结构的私有堆。1

CPython虚拟机基于栈:

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

请记住,这是针对CPython的特定内容。虽然堆栈不包含实际值,但它保留对这些对象的引用。

1: 来源


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接