Python 内存管理机制全面分析


Posted in Python onJanuary 16, 2021

内存管理:

概述

在Python中,内存管理涉及到一个包含所有Python对象和数据结构的私有堆(heap). 这个私有堆的管理由内部的Python内存管理器保证。Python内存管理器有不同的组件来处理各种动态存储管理方面的问题,如共享,分割,预分配或缓存。

在最底层,一个原始内存分配器通过与操作系统的内存管理器交互,确保私有堆有足够的空间来存储所有与Python相关的数据。在原始内存分配器的基础上,几个对象特定的分配器在同一个堆上运行,并根据每种对象类型的特点实现不同的内存管理策略。例如,整数对象在堆内的管理方式不同于字符串,元祖,或者字典。因为整数需要不同的存储需求和速度与空间的权衡。因此,Python内存管理器将一些工作分配给对象特定分配器,但确保后者在私有堆的范围内运行。

Python堆内存的管理由解释器来执行,用户对他没有控制权,即使他们经常操作只想堆内存块的对象指针,理解这一点非常重要。Python对象和其他内部缓冲区的堆空间分配是由Python内存管理器按需通过本文档中列出的Python/C API函数进行的。

内存管理机制

Python的内存管理总共分为4层(Layer0-3)

Python 内存管理机制全面分析

第一层Layer1的仅仅是对malloc的简单包装, raw memory,目的是为了兼容各个操作系统,因为不同的操作系统调用malloc的时候可能会有不同的行为结果;第二层Layer2是内存管理机制的核心,其中gc就是在这一层发挥至关重要的作用。第三层,是对象缓冲池,如Python对一些对象的直接操作,包括int,list等

对于可能被经常使用,而且是immutable的对象,如bool类型,元祖类型,小的整数,长度较短的字符串等,Python会缓存在layer3,直接供Python调用,避免频繁的创建和销毁。'

当一个对象逻辑上不被使用了,但并没有被释放,那么就存在内存泄漏,很可能会造成程序效率低下甚至崩溃

Python分配内存的时候又分为大内存和小内存,大内存以256字节为界限,对于大内存使用Malloc进行分配,而对于小内存则使用内存池进行分配,由于小内存的分配和释放是频繁的,因此内存池的使用大大提高了Python的执行效率。

引用计数

在Python中大多数对象的生命周期都是通过引用计数来管理的,引用技术也是一种最直观最简单的垃圾收集技术

每个Python对象都有一个引用计数器,用于记录多少变量指向这个对象,可以通过sys模块的getrefcount查询获得

Python 内存管理机制全面分析

每一个对象都会维护一个引用计数器,当一个对象被引用的时候,它的计数器就+1,当一个对象的引用被销毁的时候,计数器-1,当这个对象的引用计数为0的时候,说明这个对象已经没有使用了,可以被释放,就会被回收,具有实时性。由于引用计数需要维护计数器等额外的操作,为了与引用计数搭配,在内存的分配和释放上获得最高的效率,Python因此设计了大量的内存池机制。

下面这些情况引用计数+1

(1). 对象被创建: a = 4

(2). 引用被复制: y = x

(3). 被作为参数传递给函数: f(x)

(4). 作为容器对象的一个元素: a = [1, x]

下面这些情况引用计数-1

(1). 离开作用域,比如f(x)函数结束的时候,x只想的对象引用减1

(2). 引用被显式地销毁: del x

(3). 对象的一个别名被赋值给其他对象: y = 1

(4). 对象从一个容器对象中移除: l.remove(x)

(5). 容器对象本身被销毁: del l 

Python的内存管理主要以引用计数为主,引用计数机制能释放大部分无用对象,除了第一种情况,循环引用,因为循环引用的对象那个引用计数器永不为0。

循环引用,就是一个对象直接或者间接引用自己本身,导致计数器不为0

以上就是Python 内存管理机制全面分析的详细内容,更多关于python 内存管理机制的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
python对字典进行排序实例
Sep 25 Python
python使用wmi模块获取windows下的系统信息 监控系统
Oct 27 Python
Python3使用PyQt5制作简单的画板/手写板实例
Oct 19 Python
python在线编译器的简单原理及简单实现代码
Feb 02 Python
基于python中theano库的线性回归
Aug 31 Python
Python中的 is 和 == 以及字符串驻留机制详解
Jun 28 Python
python写程序统计词频的方法
Jul 29 Python
opencv实现简单人脸识别
Feb 19 Python
Python:合并两个numpy矩阵的实现
Dec 02 Python
PyCharm 专业版安装图文教程
Feb 20 Python
Python使用monkey.patch_all()解决协程阻塞问题
Apr 15 Python
使用keras实现Precise, Recall, F1-socre方式
Jun 15 Python
python des,aes,rsa加解密的实现
Jan 16 #Python
python math模块的基本使用教程
Jan 16 #Python
详解Python模块化编程与装饰器
Jan 16 #Python
删除pycharm鼠标右键快捷键打开项目的操作
Jan 16 #Python
基于pycharm 项目和项目文件命名规则的介绍
Jan 15 #Python
python制作抽奖程序代码详解
Jan 15 #Python
python中PyQuery库用法分享
Jan 15 #Python
You might like
树型结构列出指定目录里所有文件的PHP类
2006/10/09 PHP
ThinkPHP自动填充实现无限级分类的方法
2014/08/22 PHP
php获取当月最后一天函数分享
2015/02/02 PHP
php实现阳历阴历互转的方法
2015/10/28 PHP
JS获取IUSR_机器名和IWAM_机器名帐号的密码
2006/12/06 Javascript
不用写JS也能使用EXTJS视频演示
2008/12/29 Javascript
用JQuery调用Session的实现代码
2010/10/29 Javascript
JQuery对id中含有特殊字符的转义处理示例
2013/09/06 Javascript
详解Wondows下Node.js使用MongoDB的环境配置
2016/03/01 Javascript
详解js中Number()、parseInt()和parseFloat()的区别
2016/12/20 Javascript
selenium 与 chrome 进行qq登录并发邮件操作实例详解
2017/04/06 Javascript
angular.js指令中的controller、compile与link函数的不同之处
2017/05/10 Javascript
基于react后端渲染模板引擎noox发布使用
2018/01/11 Javascript
Angular使用操作事件指令ng-click传多个参数示例
2018/03/27 Javascript
Vue 菜单栏点击切换单个class(高亮)的方法
2018/08/22 Javascript
在element-ui的el-tree组件中用render函数生成el-button的实例代码
2018/11/05 Javascript
js实现通过开始结束控制的计时器
2019/02/25 Javascript
[02:33]2014DOTA2 TI每日综述 LGD涉险晋级DK闯入胜者组
2014/07/14 DOTA
初学python数组的处理代码
2011/01/04 Python
python列表操作使用示例分享
2014/02/21 Python
python检测远程端口是否打开的方法
2015/03/14 Python
python简单的函数定义和用法实例
2015/05/07 Python
在SAE上部署Python的Django框架的一些问题汇总
2015/05/30 Python
Python3实现Web网页图片下载
2016/01/28 Python
python的构建工具setup.py的方法使用示例
2017/10/23 Python
Django实现支付宝付款和微信支付的示例代码
2018/07/25 Python
Python的互斥锁与信号量详解
2019/09/12 Python
Python MongoDB 插入数据时已存在则不执行,不存在则插入的解决方法
2019/09/24 Python
Python3实现配置文件差异对比脚本
2019/11/18 Python
python多线程使用方法实例详解
2019/12/30 Python
Python 面向对象之类class和对象基本用法示例
2020/02/02 Python
python MD5加密的示例
2020/10/19 Python
详解canvas绘制网络字体几种方法
2019/08/27 HTML / CSS
草船借箭教学反思
2014/02/03 职场文书
写给老婆的检讨书
2014/02/21 职场文书
如何书写读后感?(附范文)
2019/07/26 职场文书