python

当前位置:首页 > IT面试题 > 当前文章

IT面试题

Python面试:python是怎样管理内存的

2020-07-18 140赞 老董笔记
每篇文章努力于解决一个问题!更多精品可移步文章底部。

  Python的内存管理是由私有heap空间管理的。所有的Python对象和数据结构都在一个私有heap中。程序员没有访问该heap的权限,只有解释器才能对它进行操作。

  为Python的heap空间分配内存是由Python的内存管理模块进行的,其核心API会提供一些访问该模块的方法供程序员使用。Python有自带的垃圾回收系统,它回收并释放没有被使用的内存,让它们能够被其他程序使用。

  python内存管理机制有4种方式:

  一、引用计数

  在Python中,使用了引用计数这一技术实现内存管理。

  一个对象被创建完成后就有一个变量指向他,那么就说明他的引用计数为1,以后如果有其他变量指向他,引用计数也会相应增加,如果将一个变量不再执行这个对象,那么这个对象的引用计数减1。

  如果一个对象没有任何变量指向他,也即引用计数为0,那么这个对象会被Python回收。

  二、循环引用

  引用计数这一技术虽然可以在一定程度上解决内存管理的问题。但是还是有不能解决的问题,即循环引用。

  三、标记清除和分代回收

  在Python程序中,每次你新创建了一个对象,那么就会将这个对象挂到一个叫做零代链表中(当然这个链表是Python内部的,Python开发者是没法访问到的)。

  如果创建的对象总和减去被释放的对象,达到一定的值(某个阈值),那么Python就会遍历这个零代链表,找到那些有相互引用的对象,将这些对象的引用计数减1,如果引用计数值为0了,那么就说明这个对象是可以被释放的。

  接下来再将没有被释放的对象,挪动到一个新的链表中,这个链表叫做一代链表。在零代链表清理的次数达到某个阈值后,Python会去遍历一代链表,将那些没有得到释放的对象移动到二代链表。

  同样的原理,如果一代链表清理的次数达到某个阈值后,Python会去遍历二代链表,把垃圾对象进行回收。

  四、弱代假说

  来看看代垃圾回收算法的核心行为:垃圾回收器会更频繁的处理新对象。一个新的对象即是你的程序刚刚创建的,而一个来的对象则是经过了几个时间周期之后仍然存在的对象。Python会在当一个对象从零代移动到一代,或是从一代移动到二代的过程中提升(promote)这个对象。

  为什么要这么做?这种算法的根源来自于弱代假说(weak generational hypothesis)。这个假说由两个观点构成:首先是年轻的对象通常死得也快,而老对象则很有可能存活更长的时间。

  根据假说,我的代码很可能仅仅会使用ABC很短的时间。这个对象也许仅仅只是一个方法中的中间结果,并且随着方法的返回这个对象就将变成垃圾了。大部分的新对象都是如此般地很快变成垃圾。然而,偶尔程序会创建一些很重要的,存活时间比较长的对象-例如web应用中的session变量或是配置项。

  通过频繁的处理零代链表中的新对象,Python的垃圾收集器将把时间花在更有意义的地方:它处理那些很快就可能变成垃圾的新对象。同时只在很少的时候,当满足阈值的条件,收集器才回去处理那些老变量。

文章评论

Python面试:python是怎样管理内存的文章写得不错,值得赞赏