Python的垃圾回收机制详解
作者:Jeemzz 发布时间:2023-06-03 16:03:24
引用计数
在Python源码中,每一个对象都是一个结构体表示,都有一个计数字段。
typedef struct_object {
int ob_refcnt;
struct_typeobject *ob_type;
} PyObject;
PyObject是每个对象必有的内容,其中ob_refcnt就是作为引用计数。当一个对象有了新的引用时,它的ob_refcnt就会增加,引用它的对象被删除时则减少。一旦对象的引用计数为0,该对象立即被回收,占用空间就会被释放。
优点
简单易用
实时性好,一旦没有引用就会被立即释放
缺点
需要额外空间去维护引用计数
不能解决对象的循环引用
对象的循环引用
循环引用是指两个对象相互引用且没有外部变量引用其中任何一个,导致引用链形成一个环。
>>> a = {} # 对象a的引用计数为1
>>> b = {} # 对象b的引用计数为1
>>> a['b'] = b # b的引用计数增加1
>>> b['a'] = a # a的引用计数增加1
>>> del a # a的引用计数减少1,最后a的引用为1
>>> del b # b的引用计数减少1,最后b的引用为1
在执行完del操作之后,没有任何引用指向a、b对象,但是由于这两个对象各自包含一个对对方的引用,所以引用计数始终保持在1。
按照引用计数中内存回收的原理,由于a和b的计数不为0,所以在使用引用计数法进行内存管理的时候这两个对象不会被回收,它们会一直驻留在内存中,造成内存泄露。
标记清除
标记清除机制主要用于解决循环引用问题。
标记清除算法是一种基于追踪回收(tracing GC)技术实现的垃圾回收算法。主要分为两个阶段:
标记阶段,GC会将所有的活动对象打上标记
对那些没有打上标记的非活动对象进行回收
区分活动对象与非活动对象
对象之间通过引用即指针连接在一起,构成一个有向图,对象就是这个有向图的节点,而引用关系构成这个有向图的边。从根对象(root object)出发,沿着有向边遍历对象,可达的对象会被标记为活动对象,不可达的对象就是要被清除的非活动对象。
根对象一般是全局变量、调用栈、寄存器等。
适用范围
标记清除算法作为Python辅助的垃圾收集技术,主要处理的是容器对象,因为对于字符串、数值对象等,不可能造成循环引用的问题,Python会使用一个双向链表将这些容器对象组织起来。
对于标记清除算法来说,有一个比较明显的缺点:为了清除非活动对象,需要扫描整个堆内存,哪怕只剩下小部分活动对象也需要扫描所有对象。
分代回收
分代回收是一种以空间换时间的操作方式,建立在标记清除技术的基础之上,也是Python辅助的垃圾收集技术,主要用于处理容器对象。
Python会将内存根据对象的存活时间划分为不同的集合,每个集合称为一个代,主要会被分为3代:年轻代。中年代和老年代,它们会对应3个链表,对应的垃圾收集频率随着对象存活时间的增大而减小。
新创建的对象都会被分配在年轻代,当年轻代链表总数达到上限时,会触发Python的垃圾回收机制,对可回收对象进行回收,而那些不可回收的对象会被移到中年代去。依此类推,老年代对象是存活时间最久的对象,甚至有可能存活在整个系统的生命周期内。
来源:https://www.cnblogs.com/jeemzz/p/11420725.html


猜你喜欢
- 首先你要确定错误的原因: 让IE显示详细的出错信息: 菜单--工具--Internet选项--高级--显示友好的HTTP错误信息,去掉这个选
- 现在做的一个小项目需要用到python的相关知识,但是因为太久没用一些东西都忘掉了,因此在本篇博客中记录一下python的函数和类的基础知识
- 1. Python 的参数传递Python的参数传递,无法控制引用传递还是值传递。对于不可变对象(数字、字符、元组等)的参数,更类似值传递;
- 在python命令行模式下,在IDLE中输入多行,例如if else使用tab的方式,控制缩进在最后,连续两个回车,表示结束&g
- 场景:集团中心下发本省数据时,并未按地市、业务拆分,现需要按地市、业务拆分并分发到地市。本文利用Python的pandas包实现了以上场景。
- 由于网上关于Timestamp类的资料比较少,而且官网上面介绍的很模糊,本文只是对如何创建Timestamp类对象进行简要介绍,详情请读者自
- 本文实例讲述了Yii框架引用插件和ckeditor中body与P标签去除的方法。分享给大家供大家参考,具体如下:在Yii中引用插件注:插件和
- 阅读上一篇教程:WEB2.0网页制作标准教程(9)第一个CSS布局实例如果我们想在3列布局的最后加一行页脚,放版权之类的信息。就遇到必须对齐
- 本文实例为大家分享了js图片加载淡入淡出效果展示的具体代码,供大家参考,具体内容如下HTML代码首先是图片标记的写法:<img dat
- 本文转自微信公众号:"算法与编程之美"一、前言三步搭建MUI页面主框架法包括新建含mui的HTML文件、输入mheade
- 一、表单的事件监听先介绍一下几个属性的用法1、lay-filter 事件过滤器相当于选择器,layui的专属选择器2、lay-verify
- 使用python删除excel表格重复行。# 导入pandas包并重命名为pdimport pandas as pd# 读取Excel中Sh
- 一、前言有时候觉得电影真是人类有史以来最伟大的发明,我喜欢看电影,看电影可以让我们增长见闻,学习知识。从某种角度上而言,电影凭借自身独有的魅
- 在使用selenium webdriver进行元素定位时,通常使用findElement或findElements方法结合By类返回的元素句
- 1、显式等待它指定要查找的节点,然后指定一个最长的等待时间,如果规定时间内加载出来了这个节点,就返回查找的节点;如果规定时间内没有加载出该节
- Socket 是进程间通信的一种方式,它与其他进程间通信的一个主要不同是:它能实现不同主机间的进程间通信,我们网络上各种各样的服务大多都是基
- 前言mysql是高版本,当执行group by时,select的字段不属于group by的字段的话,sql语句就会报错。错误提示:this
- Xajax是PHP一个不用刷新或者跳到其他页面,就能通过点击组件等与后台后台数据库交互的技术Xajax是php的一个插件,要想使用Xajax
- 最近业务提了一个周期提醒的功能用到了一些SQL时间函数做个记录获取当前当前日期和时间 NOW()SELECT NOW()结果:使用SQl获取
- QQ医生在广大用户心中一直以来都是清爽便捷的一款安全工具,随着QQ医生的不断发展,QQ医生团队一直在思考,怎样能够给QQ医生用户带来性能更优