【发布时间】:2012-09-18 15:24:14
【问题描述】:
我正在尝试了解 python 如何管理堆栈和堆。所以我想做一些“糟糕”的编程并导致堆栈溢出和堆溢出。我不明白为什么字符串例如进入堆栈而所有其他字符串进入堆。仅仅是设计师的约定吗?这些例子是否正确? 从我读过的内容来看,python 中的所有内容都是在堆中生成的,因为它是面向对象的,对吧?
已编辑:我认为像 C 这样的语言中的堆栈具有固定长度,但在 python 中,即使堆栈是动态分配的,正如 Anycorn 在他的回答中所说的那样。这就是为什么如果我同时尝试大字符串(在堆栈上)或列表(在堆上),我也会获得完整的内存。如果我错了,请纠正我。谢谢
来自http://docs.python.org/c-api/memory.html
Python 中的内存管理涉及一个私有堆,其中包含所有 Python 对象和数据结构。这个私人的管理 堆由 Python 内存管理器在内部确保。蟒蛇 内存管理器有不同的组件来处理各种 动态存储管理方面,例如共享、分段、 预分配或缓存。
在最低级别,原始内存分配器确保存在 私有堆中有足够的空间来存储所有与 Python 相关的数据 与操作系统的内存管理器交互。在之上 原始内存分配器,几个特定于对象的分配器操作 在同一个堆上并实现不同的内存管理策略 适应每种对象类型的特性。
这里有一些例子。您可以将它们复制粘贴到Python official visualizer 但较小的值会导致它无法运行...
堆栈溢出:
import time
word = "test "
x = word*1000000000
time.sleep(10)
print ("this message wont appear if stack overflow has occurred!")
我明白了
x = word*1000000000
MemoryError
如果我删除一个零,它就会运行。当我使用x = word*500000000 时,我得到了最大内存使用量
所以我不能使堆栈溢出,因为即使堆栈是动态分配的?
对于堆溢出:
i = 10000
test_list = [0]
while i > 0 :
test_list [:0] = test_list #insert a copy of itself at the beginning
i -= 1
现在我不明白垃圾收集器是如何在程序中运行的。它是否在堆栈和堆上运行,因为它们都是动态分配的?是因为操作系统内存管理器吗?这些东西告诉我们关于 python 编程语言的特征的什么? 这是否证明了“动态语言”或“解释”一词的合理性? 很抱歉这个问题很长,但我只需要澄清一些事情。 提前致谢!
已编辑
我找到了我要找的东西:
如果您调用,您可能会导致“真正的”堆栈溢出
sys.setrecursionlimit(N) 的 N 值大于您的系统实际可以处理的值,然后尝试递归到该深度。在某些时候,您的系统会耗尽堆栈空间,Python 解释器会崩溃。
【问题讨论】:
-
字符串对象也在堆上;可视化工具在这方面有点误导。
-
您的第一个示例导致内存错误,而不是堆栈溢出。
-
@GeoPapas 我正在使用与您相同的可视化工具。此外,较低的值不会发生 stackoverflow,尤其是因为没有堆栈增长。
-
我想你误解了什么是stackoverflow。
-
@GeoPapas 你追求的是哪个stackoverflow?耗尽堆栈内存?还是溢出堆栈缓冲区?
标签: python python-3.x heap-memory stack-overflow