我试图了解python如何管理堆栈和堆。所以我想做一些“不好”的编程,并导致堆栈溢出和堆溢出。我不明白的是为什么为什么例如字符串要堆叠而所有其他字符串要堆叠。这仅仅是设计师的同意吗?例子正确吗?从我看过的内容来看,python的一切都是自面向对象以来在堆中生成的,对吗?
编辑:我想像C这样的语言中的堆栈具有固定的长度,但是在Python中,甚至正如Anycorn在他的回答中所说的那样,该堆栈也是动态分配的。这就是为什么如果我尝试一个大字符串(在堆栈上)或一个列表(在堆上)时我也获得了全部内存的原因。如果我错了,请纠正我。谢谢
Python中的内存管理涉及一个包含所有Python对象和数据结构的私有堆。此私有堆的管理由Python内存管理器在内部确保。Python内存管理器具有不同的组件,这些组件处理各种动态存储管理方面的问题,例如共享,分段,预分配或缓存。
在最低级别上,原始内存分配器通过与操作系统的内存管理器进行交互,确保专用堆中有足够的空间来存储所有与Python相关的数据。在原始内存分配器之上,几个特定于对象的分配器在同一个堆上运行,并实现适合于每种对象类型特性的不同内存管理策略。
这里有些例子。您可以将其复制粘贴到Python官方的可视化工具中,但较小的值将导致其无法运行...
对于堆栈溢出:
importtime
word="test "x=word*1000000000time.sleep(10)print("this message wont appear if stack overflow has occurred!")
我懂了
x=word*1000000000MemoryError
如果删除一个零,它将运行。我在使用时获得最大内存使用率,x = word*500000000所以即使堆栈是动态分配的,我也无法使堆栈溢出?
对于堆溢出:
i=10000test_list=[0]whilei>0:test_list[:0]=test_list#insert a copy of itself at the beginningi-=1
现在我不明白的是垃圾收集器是如何插入程序的,因为它们都是动态分配的,所以它可以同时在堆栈和堆上运行吗?是由于O / S内存管理器引起的吗?关于python编程语言的特征,这些事情告诉我们什么?这是否证明了术语“动态语言”或“解释性”?很抱歉,这个问题很长,但是我只想澄清一下我的想法。提前致谢!
编辑
我已经找到了我想要的东西:如果您调用sys.setrecursionlimit(N)的N值大于系统实际可以处理的N值,然后尝试递归到该深度,则可能导致“真实”堆栈溢出。在某些时候,您的系统将耗尽堆栈空间,并且Python解释器将崩溃。
解决方案
与其他语言一样,您可以通过构建无限递归函数来很容易地在python中引起堆栈溢出。这在python中更容易,因为除了递归之外,它实际上根本不需要做任何其他事情。
>>>deffoo():...returnfoo()...>>>foo()Traceback(most recent call last):File"",line1,in.......File"",line2,infooRuntimeError:maximum recursion depth exceeded>>>
至于堆,这是由垃圾收集器管理的。您可以分配许多对象,最终耗尽堆空间,Python会引发一个MemoryError,但这将花费相当长的时间。您实际上是通过问题中的“堆栈溢出”示例来完成此操作的。您在堆栈上存储了对字符串的引用,该字符串占用了该进程可用的所有可用内存。根据经验,Python会在堆栈中存储对无法保证其大小的任何值的堆结构的引用。
至于所有的工作方式,从第一个示例中您可以看到python对调用堆栈的深度有一个内置的限制,即不会超过该限制。可用于堆空间的内存量由操作系统定义,但是将取决于许多因素。
这些应该是python文档的适当部分,用于有关错误本身的信息: