python的内存管理和垃圾回收机制详解


Posted in Python onMay 18, 2019

 简单来说python的内存管理机制有三种

1)引用计数

2)垃圾回收

3)内存池

接下来我们来详细讲解这三种管理机制

1,引用计数:

引用计数是一种非常高效的内存管理手段,当一个pyhton对象被引用时其引用计数增加1,当其不再被引用时引用计数减1,当引用计数等于0的时候,对象就被删除了。

2,垃圾回收(这是一个很重要知识点):

①  引用计数
引用计数也是一种垃圾回收机制,而且是一种最直观,最简单的垃圾回收技术。
在Python中每一个对象的核心就是一个结构体PyObject,它的内部有一个引用计数 ob_refcnt,当python的某个对象引用计数为0。就说明没有任何引用指向该对象,该对象就成为要被回收的垃圾了。

举个栗子: 当一个对象被创建出来,他的引用计数就会+1,当对象被引用的时候,计数继续增加,当引用它的对象被删除的时候,它的引用计数就会减少。直到变为0,此时垃圾回收机制就会把它回收。但是一旦出现循环引用,我们就得采取新的办法了。

②  标记清除
标记清除用来解决循环引用产生的问题,循环引用只有在容器对象才会产生,比如字典,元祖,列表等。首先为了追踪对象,需要每个容器对象维护两个额外的指针,用来将容器对象组成一个链表,指针分别指向前后两个容器对象,这样可以将对象的循环引用摘除,就可以得出两个对象的有效计数。

代码实栗

python的内存管理和垃圾回收机制详解

QA: 为什么要搞这两个链表
之所以要剖成两个链表,是基于这样的一种考虑:现在的unreachable可能存在被root链表中的对象,直接或间接引用的对象,这些对象是不能被回收的,一旦在标记的过程中,发现这样的对象,就将其从unreachable链表中移到root链表中;当完成标记后,unreachable链表中剩下的所有对象就是名副其实的垃圾对象了,接下来的垃圾回收只需限制在unreachable链表中即可。
③  分代回收
了解分类回收,首先要了解一下,GC的阈值,所谓阈值就是一个临界点的值。
随着你的程序运行,Python解释器保持对新创建的对象,以及因为引用计数为零而被释放掉的对象的追踪。从理论上说,创建==释放数量应该是这样子。但是如果存在循环引用的话,肯定是创建>释放数量,当创建数与释放数量的差值达到规定的阈值的时候,当当当当~分代回收机制就登场啦。
分代回收思想将对象分为三代(generation 0,1,2)
0代表幼年对象,
1代表青年对象,
2代表老年对象。
根据弱代假说(越年轻的对象越容易死掉,老的对象通常会存活更久。)
新生的对象被放入0代,如果该对象在第0代的一次gc垃圾回收中活了下来,那么它就被放到第1代里面(它就升级了)。如果第1代里面的对象在第1代的一次gc垃圾回收中活了下来,它就被放到第2代里面。

从上一次第0代gc后,如果分配对象的个数减去释放对象的个数大于threshold0,那么就会对第0代中的对象进行gc垃圾回收检查。

从上一次第1代gc后,如果第0代被gc垃圾回收的次数大于threshold1,那么就会对第1代中的对象进行gc垃圾回收检查。

从上一次第2代gc后,如果第1代被gc垃圾回收的次数大于threshold2,那么就会对第2代中的对象进行gc垃圾回收检查。

gc每一代垃圾回收所触发的阈值可以自己设置。

3,内存池

  1. Python的内存机制呈现金字塔形状,-1,-2层主要有操作系统进行操作
  2. 第0层是C中的malloc,free等内存分配和释放函数进行操作
  3. 第1层和第2层是内存池,有python接口函数,PyMem_Malloc函数实现,当对象小于256k的时由该层直接分配内存
  4. 第3层是最上层,也就是我们对python对象的直接操作

Python在运行期间会大量地执行malloc和free的操作,频繁地在用户态和核心态之间进行切换,这将严重影响Python的执行效率。为了加速Python的执行效 率,Python引入了一个内存池机制,用于管理对小块内存的申请和释放。

4,调优手段

1.手动垃圾回收
2.避免循环引用(手动解循环引用和使用弱引用)
3.调高垃圾回收阈值

以上所述是小编给大家介绍的python内存管理和垃圾回收机制详解整合,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Python 相关文章推荐
Python httplib模块使用实例
Apr 11 Python
使用Python操作MySQL的一些基本方法
Aug 16 Python
Python+django实现简单的文件上传
Aug 17 Python
Python拼接微信好友头像大图的实现方法
Aug 01 Python
python 协程中的迭代器,生成器原理及应用实例详解
Oct 28 Python
Python实现栈和队列的简单操作方法示例
Nov 29 Python
python的json中方法及jsonpath模块用法分析
Dec 06 Python
Python-openCV开运算实例
Jul 05 Python
详解Python的爬虫框架 Scrapy
Aug 03 Python
python 怎样进行内存管理
Nov 10 Python
python 基于opencv操作摄像头
Dec 24 Python
CocosCreator ScrollView优化系列之分帧加载
Apr 14 Python
Django处理多用户类型的方法介绍
May 18 #Python
Django 配置多站点多域名的实现步骤
May 17 #Python
将Python字符串生成PDF的实例代码详解
May 17 #Python
Python Django框架单元测试之文件上传测试示例
May 17 #Python
Python django框架应用中实现获取访问者ip地址示例
May 17 #Python
Python Django框架实现应用添加logging日志操作示例
May 17 #Python
Python实现通过解析域名获取ip地址的方法分析
May 17 #Python
You might like
PHP中调用JAVA
2006/10/09 PHP
discuz7 phpMysql操作类
2009/06/21 PHP
浅析php学习的路线图
2013/07/10 PHP
PHP常见的6个错误提示及解决方法
2016/07/07 PHP
php使用gd2绘制基本图形示例(直线、圆、正方形)
2017/02/15 PHP
php实现文件与16进制相互转换的方法示例
2017/02/16 PHP
PHP实现登陆并抓取微信列表中最新一组微信消息的方法
2017/07/10 PHP
详解PHP中的 input属性(隐藏 只读 限制)
2017/08/14 PHP
JS求平均值的小例子
2013/11/29 Javascript
Bootstrap Metronic完全响应式管理模板之菜单栏学习笔记
2016/07/08 Javascript
js 实现数值的千分位及保存小数方法(推荐)
2016/08/01 Javascript
js如何判断是否在iframe中及防止网页被别站用iframe嵌套
2017/01/11 Javascript
JS数组搜索之折半搜索实现方法分析
2017/03/27 Javascript
JavaScript与Java正则表达式写法的区别介绍
2017/08/15 Javascript
js取0-9随机取4个数不重复的数字代码实例
2019/03/27 Javascript
[05:05]第三天的dota2
2013/07/29 DOTA
[02:01]2018完美盛典-开场舞《双子星》
2018/12/16 DOTA
跟老齐学Python之print详解
2014/09/28 Python
儿童python练习实例
2018/05/27 Python
利用PyCharm Profile分析异步爬虫效率详解
2019/05/08 Python
Opencv图像处理:如何判断图片里某个颜色值占的比例
2020/06/03 Python
如何在windows下安装配置python工具Ulipad
2020/10/27 Python
HTML5中5个简单实用的API
2014/04/28 HTML / CSS
德国孕妇装和婴童服装网上商店:bellybutton
2018/04/12 全球购物
法国购买隐形眼镜和眼镜网站:Optical Center
2019/10/08 全球购物
日本亚马逊官方网站:Amazon.co.jp
2020/04/14 全球购物
房屋买卖协议书范本
2014/04/10 职场文书
初中班主任评语大全
2014/04/24 职场文书
护士求职信
2014/07/05 职场文书
岗位竞聘报告范文
2014/11/06 职场文书
婚礼庆典答谢词
2015/01/20 职场文书
2016年九九重阳节活动总结
2016/04/01 职场文书
2016年社区“6.26”禁毒日宣传活动总结
2016/04/05 职场文书
小学四年级班务总结该怎么写?
2019/08/16 职场文书
anaconda python3.8安装后降级
2021/06/11 Python
教你使用Jenkins集成Harbor自动发布镜像
2022/04/03 Servers