Python垃圾回收机制详解:引用计数与循环垃圾收集器

2023-09-13 16:12:37

Python垃圾回收机制

Python编程语言采用了自动垃圾回收机制,它能够自动释放不再需要的对象,并将其占用的内存返回给操作系统,供其他程序使用。这在一定程度上减轻了程序员的负担,因为他们无需手动释放内存。

引用计数机制

Python主要使用引用计数作为垃圾回收机制的一部分。每个对象都有一个引用计数器,用于记录有多少个变量引用了该对象。当引用计数器归零时,表示没有变量引用该对象,该对象就成为垃圾对象,会被垃圾回收机制自动删除。

下面是一个简单的示例来演示引用计数机制的工作原理:

class Person:
    def __init__(self, name):
        self.name = name

    def __del__(self):
        print(f'{self.name}对象被删除了')

# 创建两个对象,并相互引用
p1 = Person('Alice')
p2 = Person('Bob')

# 打印两个对象的引用计数器
print(sys.getrefcount(p1))  # 输出结果为2,包括p1和参数传递中的临时引用
print(sys.getrefcount(p2))  # 输出结果为2

# 断开对象之间的相互引用
p1 = None
p2 = None

# 观察析构函数的调用情况

在上面的示例中,我们定义了一个Person类,创建了两个对象p1和p2,并相互引用。使用sys.getrefcount()函数可以获取对象的引用计数。最后,我们将p1和p2的引用置为None,断开了它们之间的相互引用。这时,可以观察到__del__方法被调用,打印出对象被删除的消息。

循环垃圾收集器

除了引用计数机制,Python还使用循环垃圾收集器(Cycle GC)处理循环引用。循环引用指的是两个或多个对象相互引用,而没有其他对象引用它们,导致无法访问这些对象。循环垃圾收集器会定期扫描内存中的对象,检测循环引用并清理掉这些无法访问的对象。

以下是循环引用的示例:

class A:
    def __init__(self, b):
        self.b = b

class B:
    def __init__(self, a):
        self.a = a

# 创建两个对象,并相互引用形成循环引用
a_obj = A(None)
b_obj = B(a_obj)
a_obj.b = b_obj

# 对象无法通过其他引用访问到
a_obj = None
b_obj = None

# 手动进行垃圾回收
gc.collect()

在这个示例中,我们创建了两个对象a_objb_obj,它们相互引用形成循环引用。即使将它们的引用置为None,这些对象也无法通过其他引用访问到。手动调用gc.collect()可以强制执行垃圾回收,清理掉这些无法访问的对象。

需要注意的是,大多数情况下,不需要手动进行垃圾回收操作。Python的垃圾回收机制会在适当的时候自动执行。手动调用垃圾回收通常是在某些特殊情况下使用,例如在大量创建和销毁对象的情况下,以优化内存使用。

通过了解Python的垃圾回收机制,程序员可以更好地管理内存,提高代码的效率和可维护性。

小结

当对象之间存在循环引用时,Python的循环垃圾收集器会起作用。循环垃圾收集器使用了另一种策略,称为"标记-清除"。下面是循环垃圾收集器的工作过程:

  1. 标记阶段:从根对象开始,循环垃圾收集器遍历所有可达的对象,并将其标记为"存活"。
  2. 清除阶段:循环垃圾收集器扫描堆内存中的所有对象,将未标记的对象判定为垃圾对象,回收它们的内存空间。

循环垃圾收集器执行的时机由Python解释器自动控制。当达到一定条件时,例如内存占用超过阈值、CPU空闲时等,Python解释器会触发循环垃圾收集器的执行。

需要注意的是,循环垃圾收集器的工作会导致一定的性能开销。因此,在编写代码时,我们应尽量避免出现循环引用的情况,以减少垃圾回收的频率和开销。

此外,Python还提供了gc模块,允许我们对垃圾回收进行更精细的控制。通过调整gc模块的相关参数,我们可以改变垃圾回收的行为,例如禁用循环垃圾收集器、设置垃圾回收的阈值等。具体使用方法可以参考Python官方文档。

总结起来,Python的垃圾回收机制主要包括引用计数和循环垃圾收集器。引用计数用于跟踪对象的引用情况,当没有变量引用该对象时,对象会被释放。循环垃圾收集器则处理存在循环引用的情况,标记并清除无法访问的对象。通过这两种机制,Python能够自动管理内存并进行垃圾回收,减轻了程序员的负担。

详细讲解及实操

1. 程序中的垃圾问题

程序运行过程中会产生垃圾,而这些垃圾会影响程序的性能。因此,我们需要及时清理这些垃圾。

2. 垃圾的定义

在程序中,没有被引用的对象被认为是垃圾。当垃圾对象过多时,会影响程序的性能。

3. 自动垃圾回收机制

在Python中,有自动的垃圾回收机制。它会自动删除那些没有被引用的对象,无需手动处理垃圾回收。

4. 示例:使用del方法删除垃圾对象

以下是一个示例代码,展示了如何使用del方法删除垃圾对象。

class A:
    def __init__(self):
        self.name = 'A类'

    # del是一个特殊方法,它会在对象被垃圾回收前调用
    def __del__(self):
        print('A()对象被删除了~~~',self)

a = A()
b = a # 又使用一个变量b,来引用a对应的对象

print(a.name)

5. 手动处理垃圾回收

如果希望手动处理垃圾回收,可以将对象的引用置为None,或使用del语句删除引用。下面是示例代码:

# 将a设置为了None,此时没有任何的变量对A()对象进行引用,它就是变成了垃圾
a = None
b = None

6. 结束程序

最后,在代码的末尾可以加一行输入语句,以便程序执行完成后等待用户输入退出。

input('回车键退出...')

7. 垃圾回收的自动处理

Python的垃圾回收机制会自动删除那些没有被引用的对象,无需手动处理。以下是示例代码:

# 定义一个类A
class A:
    def __init__(self):
        self.name = 'A类'

    # del是一个特殊方法,它会在对象被垃圾回收前调用
    def __del__(self):
        print('A()对象被删除了~~~',self)

# 创建一个A类的实例a并引用它
a = A()

# 打印a的名称属性值
print(a.name)

# 删除a的引用
a = None

# 程序运行结束后,会自动调用垃圾回收机制删除没有被引用的对象

当程序运行结束时,Python会自动调用垃圾回收机制来删除没有被引用的对象。你可以看到,在示例代码中,当a的引用被设置为None时,对象a就成为了垃圾对象,最终会被垃圾回收机制删除。

8. 结束程序

最后,在代码的末尾可以加一行输入语句,以便程序执行完成后等待用户输入退出。

input('回车键退出...')

python精品专栏推荐


python基础知识(0基础入门)

【python基础知识】0.print()函数
【python基础知识】1.数据类型、数据应用、数据转换
【python基础知识】2.if条件判断与条件嵌套
【python基础知识】3.input()函数
【python基础知识】4.列表和字典
【python基础知识】5.for循环和while循环
【python基础知识】6.布尔值和四种语句(break、continue、pass、else)
【python基础知识】7.实操-用Python实现“文字PK”小游戏(一)
【python基础知识】7.实操-用Python实现“文字PK”小游戏(二)
【python基础知识】8.编程思维:如何解决问题-思维篇
【python基础知识】9.函数的定义和调用
【python基础知识】10.用函数编写程序 - 实操篇
【python基础知识】10.用Python实现石头剪刀布小游戏-函数实操篇
【python基础知识】11.如何debug -常见报错原因及排查思路 - 思维篇
【python基础知识】12.类与对象(一)
【python基础知识】12.类与对象(二)
【python基础知识】13.类与对象(三)
【python基础知识】13.类与对象(四)
【python基础知识】14.图书管理系统的搭建(类与对象实操)
【python基础知识】15.编码基础知识
【python基础知识】16.文件读写基础及操作
【python基础知识】16.“古诗默写题”的python实现(文件读写和编码-实操篇)
【python基础知识】17.模块的概念以及如何引入
【python基础知识】18.实操-使用python自动群发邮件
【python基础知识】19.产品思维以及流程图的使用 - 思维篇
【python基础知识】20.“午饭吃什么”的python实现(产品思维-实操篇)
【python基础知识】21.高效偷懒的正确打开方式-毕业篇
【python文件处理】CSV文件的读取、处理、写入
【python文件处理】Excel自动处理(使用 openpyxl)
【python文件处理】-excel格式处理


python爬虫知识

【python爬虫】1.爬虫基础知识
【python爬虫】2.网页基础知识
【python爬虫】3.爬虫初体验(BeautifulSoup解析)
【python爬虫】4.爬虫实操(菜品爬取)
【python爬虫】5.爬虫实操(歌词爬取)
【python爬虫】6.爬虫实操(带参数请求数据)
【python爬虫】7.爬到的数据存到哪里?
【python爬虫】8.温故而知新
【python爬虫】9.带着小饼干登录(cookies)
【python爬虫】10.指挥浏览器自动工作(selenium)
【python爬虫】11.让爬虫按时向你汇报
【python爬虫】12.建立你的爬虫大军
【python爬虫】13.吃什么不会胖(爬虫实操练习)
【python爬虫】14.Scrapy框架讲解
【python爬虫】15.Scrapy框架实战(热门职位爬取)
【python爬虫】16.爬虫知识点总结复习

更多推荐

详细解释HiveSQL执行计划

一、前言HiveSQL的执行计划描述SQL实际执行的整体轮廓,通过执行计划能了解SQL程序在转换成相应计算引擎的执行逻辑,掌握了执行逻辑也就能更好地把握程序出现的瓶颈点,从而能够实现更有针对性的优化。此外还能帮助开发者识别看似等价的SQL其实是不等价的,看似不等价的SQL其实是等价的SQL。可以说执行计划是打开SQL优

分布式任务处理

1.分布式任务调度对一个视频的转码可以理解为一个任务的执行,如果视频的数量比较多,如何去高效处理一批任务呢?1、多线程多线程是充分利用单机的资源。2、分布式加多线程充分利用多台计算机,每台计算机使用多线程处理。方案2可扩展性更强。方案2是一种分布式任务调度的处理方案。什么是分布式任务调度?我们可以先思考一下下面业务场景

排序(希尔、快速、归并排序)

文章目录1.排序的概念及其运用2.插入排序3.选择排序文章内容1.排序的概念及其运用1.1排序的概念排序:所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作。稳定性:假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,r[i

Mybatis常见面试题总结

梳理面试过程中Mybatis相关的常见问题。为保证知识点覆盖,参考了《Mybatis从入门到精通》、《深入浅出Mybatis技术原理与实战》、《Mybatis技术内幕》等书籍。Mybatis简介Mybatis是一款优秀的持久层框架(ORM框架),它支持自定义SQL、存储过程以及高级映射。Mybatis免除了几乎所有的J

2023 Google 开发者大会:Web平台新动向

目录前言一、OpeninWordPressplayground二、WebGPU三、新的核心Web指标INP四、Webview1、CustomTabs2、JavaScriptEngine五、Passkeys六、ViewTransitionsAPI七、GoogleChrome开发者工具优化1、覆盖HTTP的响应标头2、改变

《机器学习核心算法》分类算法 - 朴素贝叶斯 MultinomialNB

「作者主页」:士别三日wyx「作者简介」:CSDNtop100、阿里云博客专家、华为云享专家、网络安全领域优质创作者「推荐专栏」:小白零基础《Python入门到精通》朴素贝叶斯1、朴素贝叶斯API2、朴素贝叶斯算法实际应用2.1、获取数据集2.2、划分数据集2.3、特征归一化2.4、贝叶斯算法处理并评估3、常见问题4、

大数据-Hive

Hive简介Hive是基于Hadoop的一个【数据仓库工具】,可以将结构化和半结构化的数据文件映射为一张数据库表,并提供简单的sql查询功能。因为比直接用MapReduce开发效率更高,Hive的主要作用就是用来做离线数据分析。本质是:将HQL转化成MapReduce程序特点可扩展性Hive可以自由的扩展集群的规模,一

Mybatis深度解析:从起源到现代应用的全景视角

🌷🍁博主猫头虎带您GotoNewWorld.✨🍁🦄博客首页——猫头虎的博客🎐🐳《面试题大全专栏》文章图文并茂🦕生动形象🦖简单易学!欢迎大家来踩踩~🌺🌊《IDEA开发秘籍专栏》学会IDEA常用操作,工作效率翻倍~💐🌊《100天精通Golang(基础入门篇)》学会Golang语言,畅玩云原生,走遍大

C语言天花板——指针(初阶)

🌠🌠🌠大家在刚刚接触C语言的时候就肯定听说过,指针的重要性以及难度等级,以至于经常“谈虎色变”,但是今天我来带大家走进指针的奇妙世界。🎇🎇🎇一、什么是指针🤔指针理解的两个要点:1️⃣指针是内存中一个最小单元的编号,也就是地址2️⃣平常口语中说的指针,通常指的是指针变量,是用来存放地址的变量数据存储在内存中

Java基于SpringBoot的藏区特产销售系统的研究与实现

今天为大家带来的是基于Java+SpringBoot+Vue的藏区特产销售系统,大家有兴趣的可以看一下博主介绍:✌程序员徐师兄、7年大厂程序员经历。全网粉丝30W+,Csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌文章目录1.简介2.主要技术3功能分析4系统分析5

RabbitMQ 几种模式

一、HelloWorld模式在这一部分中,我们将用Java编写两个程序。发送单个消息的生产者和接收消息并打印出来的消费者。模型如下所示:在下图中,“P”是我们的生产者,“C”是我们的消费者。中间的框是一个队列RabbitMQ代表使用者保留的消息缓冲区。1.1生产者1.1.1添加依赖<!--指定jdk编译版本--><bu

热文推荐