python - python中如何造成栈溢出和堆溢出

标签 python python-3.x heap-memory stack-overflow

我想了解 python 如何管理堆栈和堆。所以我想做一些“糟糕”的编程并导致堆栈溢出和堆溢出。我不明白的是为什么例如字符串进入堆栈而所有其他字符串进入堆。只是设计师的同意吗?这些例子是否正确? 从我读到的内容来看,python 中的所有内容都是在堆中生成的,因为它是面向对象的,对吗?

已编辑:我想像 C 这样的语言中的堆栈具有固定长度,但在 python 中,即使堆栈是动态分配的,正如 Anycorn 在他的回答中所说的那样。这就是为什么如果我同时尝试一个大字符串(在堆栈上)或一个列表(在堆上),我也会获得完整的内存。如果我错了请纠正我。谢谢

来自 http://docs.python.org/c-api/memory.html

Memory management in Python involves a private heap containing all Python objects and data structures. The management of this private heap is ensured internally by the Python memory manager. The Python memory manager has different components which deal with various dynamic storage management aspects, like sharing, segmentation, preallocation or caching.

At the lowest level, a raw memory allocator ensures that there is enough room in the private heap for storing all Python-related data by interacting with the memory manager of the operating system. On top of the raw memory allocator, several object-specific allocators operate on the same heap and implement distinct memory management policies adapted to the peculiarities of every object type.

这里有一些例子。你可以复制粘贴到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 编程语言的特征是什么? 这是否证明术语“动态语言”或“解释”的合理性? 很抱歉问了这么长的问题,但我只需要澄清一些事情。 提前致谢!

已编辑
我找到了我要找的东西: 如果你打电话,你可能会导致“真正的”堆栈溢出 sys.setrecursionlimit(N) 的 N 值大于您的系统实际可以处理的值,然后尝试递归到该深度。在某些时候,您的系统将用完堆栈空间,Python 解释器将崩溃。

最佳答案

与其他任何语言一样,通过构建无限递归函数,您可以很容易地在 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有一个内置的限制 它不会超过的调用堆栈的深度。然而,可用于堆空间的内存量由操作系统定义,并且取决于许多因素。

这些应该是 python 文档的适当部分,用于提供有关错误本身的信息:

关于python - python中如何造成栈溢出和堆溢出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12611264/

相关文章:

python - ConfigParser - 打印 config.sections() 返回 []

python - 计算二维向量之间角度的最快方法

python - 派林特 W0108 : Lambda may not be > necessary (unnecessary-lambda)

c# - .net 中有哪些不同的堆?

python - 根据另一个 bool 列表从一个列表中获取元素

python - 在 Python 脚本中使用输入变量

django - 如何将类属性添加到 Django 身份验证登录表单?

c - 堆栈大小会在运行时增长吗?

objective-c - Objective-C 方法的执行是否会创建 "frames on the stack"?

python - manage.py syncdb 不为某些模型添加表