一个由引用计数引起的Python内存管理小瑕疵
这个代码是在看了“码农高天”的视频照模仿的。
Python 的垃圾回收(Garbage Collection,以下简称 GC)算法是基于引用计数的方式实现的,即 Python 不会记录一个变量被哪几个变量所引用(函数也可以理解为一种变量),只会标记一个变量被引用了多少次。
这种策略可以以极低的性能成本实现内存的自动回收功能,常在退出函数调用时使用,用于销毁其引用的所有变量。
这种策略虽然大幅增强 GC 算法的性能,但是一旦出现变量间的相互引用现象(即存在环路),那么基于引用计数的 GC 算法将无法有效识别出无用变量。也就无法实现实时的变量销毁功能。
以下是一段测试 GC 算法的样例代码,其中 __del__
是 Python 定义的一个魔术方法,当一个对象将要被销毁时,GC 会自动调用该方法。该魔术方法常用于释放预先设置的系统资源。我们可以通过该魔术方法来观察对象何时被销毁。
from typing import Any, Optional
import gc
class Object:
def __init__(self, name: str) -> None:
self.obj: Optional[Any] = None
self.name: str = name
def __del__(self):
print(f"{self.name} is deleted")
def main():
a = Object("A")
b = Object("B")
a.obj = b
b.obj = a
if __name__ == "__main__":
main()
print("start Garbage Collection")
gc.collect()
print("program end")
当 main
函数执行完成后,可以看到两个声明的变量A和B并没在main函数执行完成后销毁,而是在调用了 gc.collect()
之后才成功销毁。如下图所示:
实际上为了解决这一问题,Python还引入了循环垃圾检测(Cycle Detection)算法用于解决此类问题。该算法将会从根对象(全局变量容器)开始扫描并标记是否引用,然后再统一清除未引用的变量。不过由于该算法性能开销较大,因此触发该算法的条件较为苛刻,如使用内存快满了或手动调用 gc.collect()
时才会开始扫描。
分代回收算法则是循环垃圾检测的一种补充算法,在降低了性能开销的前提下,显著提升了垃圾回收效率。
经常会有各种错别字,请留言提醒,或者向我邮件 mailto:somata@foxmail.com.
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 本地部署 DeepSeek:小白也能轻松搞定!
· 传国玉玺易主,ai.com竟然跳转到国产AI
· 自己如何在本地电脑从零搭建DeepSeek!手把手教学,快来看看! (建议收藏)
· 我们是如何解决abp身上的几个痛点
· 如何基于DeepSeek开展AI项目