IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Python知识库 -> Python的垃圾回收机制GC(持续更新~) -> 正文阅读

[Python知识库]Python的垃圾回收机制GC(持续更新~)

我们知道,计算机的内存是有限的,我们让计算机帮我们干活,也就是处理数据,这些数据会占用计算机的内存,那么如果不合理的使用有限的内存,很快就会内存占满,导致计算机干不动活了。

那么在我们让计算机帮我们跑程序的时候,会进行大量的数据存储和计算,占用的内存空间,如果不及时的清理,那么就会出现内存泄露(我看有的文章或者视频说是内存溢出,但是我觉得不是,内存泄露就是申请的内存空间没有被释放,导致一直占着这个坑,不干活,所以叫内存泄露,而内存溢出,就是比如我需要给一个数据什么一块内存空间,但是这个内存空间不够放的,那么这个就是内存溢出。)
回到正题,内存本来就是有限的,你再给我泄露一点,那么可用的就变得更少了。

所以,为了解决合理利用内存空间,每个语言都有自己的内存回收机制,也就是垃圾回收机制,GC(garbage collection),Python也一样。

Python的垃圾回收机制是由它变量(其实叫对象,因为Python中一切皆对象)定义的方式来决定的,我们知道Python的变量声明的时候,是不指定类型的,声明的时候必须赋值,否则会报错,并且Python的变量声明之后,是给变量一个值的引用,并不是和c语言一样,直接就给这个变量分配块空间存放它的值了。
声明一个变量:a = 1,其实就是在内存中开辟一个空间放置值1,然后把值1的引用,也就是相当于地址的东西给a,那么a就能够访问1.此时1的被引用的次数就变成了1.
在这里插入图片描述
如果这个时候,再声明一个变量:b=a.那么就相当于b也拿到了1的引用,它们同时指向1,这个时候1的引用次数为:2
在这里插入图片描述
那么,如果我们声明了很多变量,内存占用也会增多,可用的变少,内存中的数据肯定分为:已经不使用的和正在使用的,那么计算机如何知道哪些被使用,哪些没有被使用呢,那就是引用,如果一块内存中的数据,没有被引用,也就是引用的次数为0,那么就会认为这个数据是垃圾数据,大于0次数的引用认为是有用的数据,垃圾数据肯定是及时清理掉,才能释放掉内存空间,给别的程序使用。
所以Python的垃圾回收机制就是当一块内存中的数据被申请后,他会有一个变量叫refchain变量,用来存放这个数据被引用的次数,被引用一次,就会加1.删除引用,就会减1,当减为0的时候,这个数据就会被Python的垃圾回收器给回收了,这块内存就会被释放,给别人使用。

上面的垃圾回收机制看着没什么问题,挺简单的。但是有一种特殊情况的数据,会被漏掉,什么样的数据呢,就是普通的数据,只是这个数据被别的数据引用,别的数据还引用它。其实这两块数据并没有在外部被使用,导致它们自己形成了一个环,这个环就叫做循环引用。
比如下面的代码就会导致形成环:

a = [1]
b = [2]
a.append(b)
b.append(a)

print(a,b)

在内存中引用是下面这样的:
在这里插入图片描述
可以看到上面变量a和变量b分别指向两块内存空间,这两块内存空间,内部互相引用。如果这个时候,del a 和del b.只会是下面这样:
在这里插入图片描述
也就是a和b对这两块的内存的引用都切断了,但是这两块内存的引用次数仍然不为0,就是因为它们内部互相引用,这样的话,Python的垃圾回收机制就会认为这个是个有用的数据,会保留,导致这块内存在程序运行期间一直存在,这样肯定是不行的,如果存在很多这样的数据,那么就会导致内存被浪费很多。为了解决这个循环引用的问题。就引出了标记-清除的一种垃圾回收方案。

在介绍标记-清除之前,再给一个例子看下,当一个数据在内存中的引用为0时,会自动调用__del__方法;

class INT(int):
    def __del__(self):
        print("我被释放了")
        
a = INT(1)
print(a,type(a))
a = 3
print(a,type(a))

运行结果:

1 <class '__main__.INT'>
我被释放了
3 <class 'int'>

可以看到在把3的引用给a的时候,1的引用已经没了,这个时候会自动去调用del方法,而我们重写了这个方法,所以能够看到打印。

接下来介绍标记-清除:

上面的介绍说:标记-清除是为了解决垃圾回收中循环引用的问题,就是说

  Python知识库 最新文章
Python中String模块
【Python】 14-CVS文件操作
python的panda库读写文件
使用Nordic的nrf52840实现蓝牙DFU过程
【Python学习记录】numpy数组用法整理
Python学习笔记
python字符串和列表
python如何从txt文件中解析出有效的数据
Python编程从入门到实践自学/3.1-3.2
python变量
上一篇文章      下一篇文章      查看所有文章
加:2021-10-27 12:47:35  更:2021-10-27 12:47:49 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/15 22:51:47-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码