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内存管理&垃圾回收原理

??引用计数器?主,?标记清除?和?分代回收?辅,+??缓存机制??

1.??引用计数器:

?1.1 环状的双向链表refchain:?

在python程序中,?创建?的任何一个?对象?都会?加入到?这个 refchain?双向链表?中。

例:?

name = 'wuhan'
new = name

操作系统会在内存中开辟一块空间存name这个对象,在内存中会name这个对象创建一些数据 (即,一个结构体,包括?上一个对象位置、下一个对象位置,本数据的数据类型,本数据的引用个数(相同的)以及?具体数据(不同的)),new=name,操作系统不会为new开辟新空间,会在name开辟空间中的引用处标记2,即两个位置使用’wuhan‘这块空间。

# 内存中会创建一些数据:[上一个对象位置,下一个对象位置,类型,引用个数,val=18]
age = 18

# 内存中会创建一些数据:[上一个对象位置,下一个对象位置,类型,引用个数,items=元素,元素个数]
hobby = ["篮球","美女"]

C源码:

?1.2 类型封装的结构体:

?1.3 引用计数器:

当python程序运行时,会根据对象数据类型不同,找到对应的结构体,根据结构体中的字段来创建相关的数据,然后将对象添加到refchain这个双向链表中

C源码中有两个关键的结构体:PyObject、PyVarObject

创建对象的结构体中,都有ob_refcnt这个字段,这个就是引用计数器创建对象的时候ob_refcnt的值默认是1,当有其他变量对这个对象进行引用时,引用计数器就会发生变化

~ 引用:?

# b 与 a 指向同一块内存地址 都对9999这个 值 进行了引用
a = 9999
b = a

~ 删除引用 :当对象的引用计数器为0时,意味着没有人再使用这个对象了,这个对象就是垃圾,对这个对象进行垃圾回收回收:1.对象从refchain双向链表中移除;2.将对象进行销毁,把内存归还给操作系统。

a = 9999
b = a
del b # b变量删除,b对应对象的引用计数器值 - 1
del a # a变量删除,a对应对象的引用计数器值 - 1

# 当对象的引用计数器为0时,意味着没有人再使用这个对象了,这个对象就是垃圾,对这个对象进行垃圾回收
# 回收:1.对象从refchain双向链表中移除;2.将对象进行销毁,把内存归还给操作系统。

1.4 引用计数器一个bug ,即循环引用问题

实际上del v1 和del v2 之后没有对两个列表进行引用的对象了,但是引用计数器不为0,不能被回收,形成垃圾,占用内存

2.??标记清除:

标记清除?引入的目的:?为了解决引用计数器循环引用的不足

标记清除?实现在python的底层中再维护一个链表?,链表中可能存在循环引用对象(如 list \ tuple \ dict \ set)

某种情况下,在python内部会去扫描,可能存在循环引用的链表中的每个元素,检查是否有循环引用,如果,则让双方的引用计数器-1,如果双方的引用计数器都为0,则是垃圾,该被回收;如果双方的引用计数器不为0,则不动该对象。每个元素的子元素都要被扫描一次。

标记清除 问题

a. 什么时候扫描?

b.?每个元素的子元素都要被扫描一次,可能存在循环引用的这个链表?扫描的代价大!耗时久。

3.??分代回收:

分代回收?引入目的:为解决标记清除的问题;

分代回收?实现将可能存在循环引用的对象?维护成?3个链表0代、1代、2代?每一代都是一个双向链表。

分代回收?扫描时间:

0代:0代对象个数达到700个,扫描一次;

1代:0代扫描10次,1代扫描一次;

2代:1代扫描10次,2代扫描一次;

分代回收?过程创建对象,把有可能存在循环引用的对象加入到refchain和0代链表,0代扫描,ob_refcnt自减1,如果ob_refcnt值为0,进行垃圾回收;否则把数据从0代?升级?1代,0代里扫描后,0代理就没有数据了,该回收的回收,该升级的升级。

4.小结 :

1)在python中维护了一个refchain的双向环状链表,这个链表存储程序创建的所有对象。

2)每种类型的对象中都包含一个ob_refcnt引用计数器的值,当有引用时ob_refcnt+1,删除引用时ob_refcnt-1;当引用计数器的值变为0时进行垃圾回收(对象销毁,从refchain中移除该对象)。

3)但是,在python中对于那些可以有多个元素组成的对象(list、tuple、set、dict),可能存在循环引用的问题,为了解决这个问题,python引入了标记清除和分代回收。也就是在python内部维护了四个链表:refchain(维护所有对象),2代(10次),1代(10次),0代(700个对象)。在源码内部当达到各自的阈值时,就会触发扫描链表进行标记清除,即有循环引用则各自-1。

4)python的源码内部在上述的流程中提出了优化机制 :缓存机制。

5.?缓存机制:?

?5.1 池:(int)

为避免重复创建和销毁一些常见的对象,维护池。

启动解释器时,python内部帮我们创建-5,-4,......,257?,引用如上这期间的数据不会再创建新对象,直接引用小数据池中的数据对象,小数据池中的对象永远不会被回收。

v1 = 7 # 内部不会开辟内存,直接去池中获取,加到refchain链表中
v2 = 9 # 同上
v3 = 9 # v3 与 v2 指向同一块内存

print(id(v2),id(v3))
v4 = 999 # 开辟一块内存,创建一个新对象,加入到refchain
v5 = 666 # 开辟一块内存,创建一个新对象,加入到refchain
v6 = 666 # 开辟一块内存,创建一个新对象,加入到refchain

?5.1 free_list:(float、list、tuple、dict)?

当引用计数器为0时,按理说应该回收该对象了?,但是python为了优化,不会直接回收,而是将这些数据添加到free_list列表中,以后再去创建对象,不重新开辟内存,而是直接使用free_list。free_list是有个数限制的,如80个。free_list满了,放不下的数据,才会被销毁

v1 = 3.14 # 开辟内存,内部存储结构体中定义的那几个值,并存到refchain中

del v1 # refchain中移除,将对象添加到free_list中

v9 = 999.99 # 不会开辟内存,直接去free_list中获取对象,将对象内部数据进行初始化,在放到refchain中

由上,当引入计数器为0时,有时候直接销毁,有时候被缓存管理起来。?

?

int、float、str对象只会放到refchain中,ob_refcnt=0,放到free_list中(未满),free_list满了销毁。

dict、list、set、tuple对像会放到refchain中,以及0代,ob_refcnt=0,放到free_list中(未满),free_list满了销毁。

?整理

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-03-12 17:47:47  更:2022-03-12 17:51:58 
 
开发: 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/26 13:41:36-

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