python中的垃圾回收机制是以引用计数器为主,标记清除和分代回收为辅的 + 缓存机制

1.引用计数器

在python内部维护了一个名为refchain的环状双向链表,在python中创建的任何对象都会放在refchain中

name = "kunmzhao"
age=18

在python中创建的对象,在底层是由C语言中的结构体存储的

在这些结构体中存储这上一个对象,下一个对象,对象类型和引用个数

1.1 引用计数

在python运行过程中,当我们创建一个对象的时候,会根据数据类型找到对应的结构体,创建对象,然后将对象添加在refchain中,并且引用计数为1.当对象被引用的时候就会+1,当对象被del的时候就-1

当一个对象的引用计数=0的时候,代表着这个对象就是垃圾,需要被回收,将对象从refchain中移除

1.2 循环引用问题

当两个列表互相嵌套的时候,就出现了循环引用,不解决的话就出现了内存泄漏

2.标记清除

标记清除的目的是为了解决引用计数中的循环引用问题

实现原理:在python内部再维护一个双线链表,用于存放可能存在循环引用的对象(列表,字典,元组,集合类型),在一定条件下出触发链表的全部扫描,检查是否有循环引用,如果存在,则将双方的引用计数-1,如果为0则进行垃圾及回收

3.分代回收

目的是为了优化标记清除,因为如果标记清除维护的链表很大,每次都遍历会非常消耗性能,为此分代回收维护了3个链表,3个链表代表着不同的扫描阈值,当达到阈值之后才会触发对应链表的扫描

  • 0代:0代中对象的个数达到700个则扫描一次

  • 1代:0代扫描10次,则1代扫描一次

  • 2代:1代扫描10次,则2代扫描一次

将可能存在循环引用的对象放在0代的链表中,当0代中的对象个数超过700个就会触发一次链表扫描,将引用个数为0的回收,不为0的提升到1代链表中,并将0代扫描次数设置为1,当0代扫描次数为10次的时,就会触发1代进行扫描,将引用个数为0的进行回收,不为0的提升为2代,并将1代扫描次数设置为1

小结:在python中,维护了一个refchain的双向链表,存放着python中创建的所有对象,每个对象都有一个ob_refcnt的引用计数器,变量被引用一次,则个数+1,删除一次,个数-1,当个数为0,则进行垃圾回收,但是由于循环引用的问题,python引入了标记清除和分代回收,又维护了3个链表,0代,1代和2代,代表着不同的阈值,当各自达到对应的阈值就会触发扫描链表,进行标记清除

4.缓存机制

频繁的申请和销毁内存是非常消耗时间的,为此又引入了缓存机制,包括缓存池和free_list

4.1缓存池

池的做法是预先缓存一些常见的对象比如-5到256的整型对象,和ASCII字符表等。当程序中定义了一个小的整型对象时,不需要从内存中申请内存,直接从池中获取即可

4.2 free_list

free_list的做法是将程序本来删除的对象,没有直接销毁而是放在一个名为free_list的数组中。后面当程序中重新创建一个相同类型的对象时,不必新开辟空间而是直接从free_list中获取对象,重新进行初始化并放入到refchain中去。

class Foo(object):
name = 'kunmzhao' def __init__(self, name):
self.name = name def send_msg(self):
print(self.name) foo = Foo('kunmzhao') # 2324775989200
print(id(foo))
del foo

foo1 = Foo('Victor') # 2324775989200
print(id(foo1))

最新文章

  1. java上传xls文件
  2. lsll 加载段限长指令
  3. original.txt和提交的页面输出的文字的混合文件
  4. The specified child already has a parent错误
  5. 2003服务器断开rdp后会自动注销。
  6. HDU Train Problem I 1022 栈模拟
  7. Source Insight 3.X 插件支持utf8,完美解决中国乱码,连接到美丽的轮廓
  8. 使用Bootstrap + Vue.js实现 添加删除数据
  9. HDU 4162 Shape Number(字符串,最小表示法)
  10. 韩信点兵(hanxin)
  11. Visual Studio 2010 VS IDE 编辑界面出现绿色的点 去掉绿色的空格点
  12. 怎样将本地web项目部署到腾讯云服务器上?
  13. Python源码学习(一)
  14. 步步为营-20-XML
  15. java 下载网络图片
  16. Java反射 Introspector
  17. 突破MSDE 的2GB数据限制
  18. Java的符号扩展与零扩展
  19. Divisibility by 25 CodeForces - 988E(模拟)
  20. F2eTest和uirecorder自动化测试环境部署填坑记录

热门文章

  1. 【java】学习路径25-ArrayList类,Vector类,LinkedList类的使用和区别,Iterator迭代器的使用
  2. Dapr中国社区活动之 分布式运行时开发者日 (2022.09.03)
  3. 第三十九篇:Vue3 watch(ref和reactive的监视)
  4. 10_Linux基础-SHELL入门1
  5. Python获取时光网电影数据
  6. Oracle 与 PostgreSQL 函数行为的差异引发性能差异
  7. Sentinel 源码分析-限流原理
  8. SonarQube支持Gitlab授权登录
  9. MongoDB集群搭建---副本和分片(伪集群)
  10. CentOS 7 firewalld 配置详解