我试图了解python如何管理堆栈和堆。所以我想做一些“坏”编程并导致堆栈溢出和堆溢出。我不明白的是为什么字符串例如去堆叠而其他所有去堆。这只是设计师的一致意见吗?这些例子是否正确? 从我所看到的内容中,python中的所有内容都是在堆中生成的,因为它面向对象,对吧?
已编辑 :我认为像C这样的语言的堆栈有一个固定的长度,但在python中,即使堆栈也是动态分配的,因为Anycorn在他的回答中说。这就是为什么如果我尝试一个大字符串(在堆栈上)或一个列表(在堆上)我也获得完整的内存。如果我错了,请纠正我。感谢
来自http://docs.python.org/c-api/memory.html
Python中的内存管理涉及包含所有内容的私有堆 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
现在我不明白的是垃圾收集器如何在程序中启动。它是否在堆栈和堆上运行,因为它们都是动态分配的?是由于O / S内存管理器吗?这些事情告诉我们有关python编程语言的特征的什么? 这是否可以证明“动态语言”或“解释”一词的合理性? 很抱歉这个问题很长,但我只想澄清一些事情。 提前谢谢!
EDITED
我找到了我要找的东西:
如果你打电话,你可以导致“真正的”堆栈溢出
值{N}大于系统实际可以处理的sys.setrecursionlimit(N)
然后尝试递归到该深度。在某些时候,你的系统将耗尽堆栈空间,Python解释器将崩溃。
答案 0 :(得分:7)
通过构建一个无限递归的函数,你可以在python中很容易地导致堆栈溢出,就像在任何其他语言中一样。这在python中更容易,因为除了递归之外它实际上不需要做任何事情。
>>> def foo():
... return foo()
...
>>> foo()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
.......
File "<stdin>", line 2, in foo
RuntimeError: maximum recursion depth exceeded
>>>
对于堆,由垃圾收集器管理。您可以分配大量对象并最终耗尽堆空间,Python将引发MemoryError
,但这需要相当长的时间。你实际上是通过问题中的“堆栈溢出”示例来实现的。您在堆栈上存储了对字符串的引用,该字符串占用了进程可用的所有可用内存。根据经验,Python会在堆栈上存储对堆结构的引用,以获取无法保证大小的任何值。
至于它是如何工作的,从第一个例子可以看出python有一个内置的限制 它不会超过的调用堆栈的深度。可用于堆空间的内存量由OS定义,并且取决于许多因素。
这些应该是python文档的相应部分,用于错误本身的信息:
答案 1 :(得分:5)
据我所知,当涉及到实际的堆栈实现时,python堆栈(在默认分发中)实际上是基于堆内存(用malloc
分配的内存)。因此,您不能导致堆栈溢出,但您可能会耗尽内存。你看到的计算机速度减慢是因为内存被交换到磁盘,程序非常慢。
通常,您不知道解释/字节编译语言如何实现其堆栈,但大多数情况下它并未在堆栈内存中实现,因此您不会导致堆栈溢出。可以使用alloca
实现Python,但为什么?
比照。 CPython - Internally, what is stored on the stack and heap?
尝试使用编译语言,C ++,Fortran等编译机器代码的相同实验。