Python内存管理

Python 内存管理的三个阶段:

1. 引用计数

引用计数是 Python 内存管理的第一道防线。当一个对象被引用时,Python 会为其分配一段内存,并将其引用计数设置为 1。当对象被多次引用时,其引用计数会逐渐增加。当一个对象不再被引用时,Python 将其引用计数减少 1。当一个对象的引用计数变为 0 时,Python 就会自动将其从内存中删除,从而节省内存空间。 引用计数机制的优点是简单、高效。当有变量引用一个对象时,Python 只需要增加其引用计数。当没有变量引用一个对象时,Python 只需要将其引用计数减少并从内存中释放即可。这种方式可以及时回收许多无法访问到的对象,避免了内存因过多的垃圾对象而耗尽。 但是引用计数机制也存在一些问题。

引用计数的问题:

例如,当存在循环引用时,引用计数机制就不能够清除对象。循环引用是指两个或多个对象之间相互引用,但是它们并没有变量引用它们。这样的话,它们的引用计数一直不为 0,这些对象就无法被释放,从而导致内存泄漏。 为了解决循环引用的问题,Python 引入了垃圾回收机制。Python 的垃圾回收机制是基于标记清除和分代回收两种算法的,可以同时解决循环引用和内存泄漏问题,避免内存过多消耗。

2.标记清除

​ 标记清除机制是指从根对象开始遍历所有对象,将所有能访问到的对象标记出来。然后将没有标记的对象视为无用对象,Python 会自动销毁这些对。其中,根对象可以是当前正在运行的函数的本地变量、全局变量、以及引入的模块等。 标记清除机制的优点是可以较好地处理循环引用,但是它的缺点是效率较低。因为在进行垃圾回收时,需要遍历整个内存空间,并对所有对象进行标记。

3.分代回收

Python 将对象按照年龄分为三代,年龄越小的对象就越在前面。新分配的对象属于一代,如果存活下来,会逐渐晋升到二代和三代。一代中的垃圾回收由 Python 自动完成了,而二代和三代则采用分代回收机制进行处理。

三代的回收采用了分区管理,将一代和二代分成多个区域,每个区域的大小都是固定的。这样,垃圾回收就只需要扫描可回收区里的内容,就可以大大减少扫描范围,从而提升了垃圾回收的速度。

二代的回收采用了复制算法。复制算法将存活的对象复制到另一块地址空间,然后清空原来的地址空间。这样一来,复制到的地址空间里是一个完整的内存块,没有内存碎片问题,回收效率较高。

同时,Python 还把二代分成两部分,分别是名称为商业和非商业的部分。不同部分采用不同的回收策略。商业部分采用标记清除算法,非商业部分采用分区管理和复制算法。

采用分代回收机制,是因为在实际开发中,大部分对象的生命周期都比较短,在一次垃圾回收中,只有极少数对象需要被回收。而对于生命周期较长的对象,一次回收可能并不能完全清空所有的无用对象。因此,将对象按生命周期划分成多代,可以针对不同的对象行采用不同的回收策略,提高回收效率。

posted @ 2023-04-01 22:53  我不知道取什么名字好  阅读(46)  评论(0编辑  收藏  举报