Python中的内存管理机制
Python是如何进行内存管理的
python引用了一个内存池(memory pool)机制,即pymalloc机制,用于管理对小块内存的申请和释放
1.介绍
python和其他高级语言一样,会进行自动的内存管理。它使用引用计数机制检测为对象分配的内存是否可以被释放。然后,在Python中内存永远不会返还给操作系统,Python会持有这些内存并在需要时重新使用它们。在很多场景下,这个特性可以减少内存申请和释放所带来的性能损耗;但对于需要长时间运行的Python进程来讲,Python将会占用大量的内存。如果进程使用内存的峰值远大于平均值,这将会造成内存的浪费从而影响本进程甚至是系统中其他进程的性能。
2.Pymalloc
Python使用pymalloc管理内存。在Python中,会频繁的创建和删除很多小对象,如果这些对象的内存申请和释放都使用malloc()和free(),将会带来严重的性能问题。因此,pymalloc分配一系列256KB内存块,称之为arena。每个arena分割为4KB大小的内存池Pool,每个Pool在切分为固定大小的Block。在内存分配时,分配给进程的就是这些Blocks。


3.内存分配


上图中展示了一个usedpool数组,此数组按内存大小组织,每个大小对应一个pool链表,每个pool链表中有多个空闲的Block。在分配内存时,Pymalloc先判断是否存在要申请的大小的pool,如果存在的话,直接从pool中获取一个free Block返回给应用程序,这个过程非常迅速。如果分配完这个Block后此pool变为一个空pool,则将这个Pool从链表中移除。
如果在usedpool中找不到大小匹配的pool,需要在freepool中查找可用的pool。在找不到的情况下,首先会尝试在最后一个arena中是否存在可用的内存,如果有的话则分配一个非freepool使用;如果不存在这样的arena,将会通过malloc()分配一个新的arena。在freepool中找到一个可用的Pool后,会将此Pool切分为固定大小的Pool并加入到userdpool中,并在其中分配一个Free Block应用程序。
4.内存释放

在应用程序要释放一个Block时,过程和分配的过程比较相似。首先会根据Block找到此Block所归属的ool,然后将此Block加入到Pool的Free Block列表中。如果Pool当前是空的,还会将这个Pool加入到usedpool的链表中。如果在Block加入到Free Block后所有的Block都是Free的,会将此Pool从usedpool移动到freepool中

上面的过程可以看到,内存释放的过程基本就是内存申请的反过程,但唯一的区别是缺少了将freepool反换费arena,并将arena通过free()返还给操作系统的步骤。
5.基本数据类型的内存分配
Python中有一小部分的对象是不使用pymalloc进程内存分配的,主要是integer/float/list/dict。为了提升这些常用对象的内存使用效率,这些对象是保存在单独的列表中的。
Python通过malloc()为Integer/Floal两种类型分配大约1KB大小的内存块列表,这些列表被当做Integer/Float的数组使用,而不是使用Pymalloc的分配的8字节的整数倍大小的Block,以减少内存消耗。在创建一个新的Integer/Float对象时,字直接从这个内存列表中获取数据,或是重新分配一块新的Block;在释放时对应的Block重新加入到列表中。这些Block也是不会被返还给操作系统的。
Python为list/dict采用不同的策略,会最多保留80个空闲的list/dict,如果多余80个,多出的会被释放
Python中的内存管理机制的更多相关文章
- Android中的内存管理机制以及正确的使用方式
概述 从操作系统的角度来说,内存就是一块数据存储区域,属于可被操作系统调度的资源.现代多任务(进程)的操作系统中,内存管理尤为重要,操作系统需要为每一个进程合理的分配内存资源,所以可以从两方面来理解操 ...
- Python 中的内存管理
Python 中一切皆对象,这些对象的内存都是在运行时动态地在堆中进行分配的,就连 Python 虚拟机使用的栈也是在堆上模拟的.既然一切皆对象,那么在 Python 程序运行过程中对象的创建和释放就 ...
- cocos2dx中的内存管理机制及引用计数
1.内存管理的两大策略: 谁申请,谁释放原则(类似于,谁污染了内存,最后由谁来清理内存)--------->适用于过程性函数 引用计数原则(创建时,引用数为1,每引用一次,计数加1,调用结束时, ...
- python中的内存管理
不像大多数编译型语言,变量必须在使用之前声明名字和类型,在python中,变量在第一次被赋值时自动声明.在变量创建时,python解释器会根据语法和右侧的操作数来决定新对象的类型,在对象创建后,一个该 ...
- 20191125:Python中的上下文管理机制with
20191125:with上下文管理 with是一个上下文管理器,用于执行代码块所需要的运行的时候的上下文入口和出口.上下文管理器的典型用法包括保存和还原各种全局状态,锁定和解锁资源,关闭打开的文件等 ...
- 【python测试开发栈】—python内存管理机制(二)—垃圾回收
在上一篇文章中(python 内存管理机制-引用计数)中,我们介绍了python内存管理机制中的引用计数,python正是通过它来有效的管理内存.今天来介绍python的垃圾回收,其主要策略是引用计数 ...
- IOS中内存管理机制浅解
我们知道在程序运行过程中要创建大量的对象,和其他高级语言类似,在ObjC中对象时存储在堆中的,系统并不会自动释放堆中的内存(注意基本类型是 由系统自己管理的,放在栈上).如果一个对象创建并使用后没有得 ...
- C++中的内存管理
在C++中也是少不了对内存的管理,在C++中只要有new的地方,在写代码的时候都要想着delete. new分配的时堆内存,在函数结束的时候不会自动释放,如果不delete我分配的堆内存,则会造成内存 ...
- Cocos2d-x开发中C++内存管理
由于开始并没有介绍C++语言,C++的内存管理当然也没进行任何的说明,为了掌握Cocos2d-x中的内存管理机制,是有必要先了解一些C++内存管理的知识.C++内存管理非常复杂,如果完全地系统地介绍可 ...
随机推荐
- Angular 中的 dom 操作(ViewChild)以及父子组件中通过 ViewChild 调用子组件的方法
<app-header #header></app-header> <div #myBox> 我是一个dom节点 </div> <button ( ...
- SQL语言Select经典语句
-- 示例数据 Select * From Employee Select * From Department -- 返回工资最高的员工的信息 Select * From Employee where ...
- 阶段5 3.微服务项目【学成在线】_day09 课程预览 Eureka Feign_13-课程预览功能开发-CMS页面预览接口测试
5.2 CMS页面预览测试 CMS已经提供了页面预览功能,课程预览功能要使用CMS页面预览接口实现,下边通过cms页面预览接口测试课 程预览的效果. 1.向cms_page表插入一条页面记录或者从cm ...
- 阶段5 3.微服务项目【学成在线】_day17 用户认证 Zuul_18-身份校验-测试
在顶级域名下配置 网关的地址在上面配置一下 重启nginx 拒绝访问后面的代码都加上 return null 开始测试 换成域名的方式访问 有cookie.但是拿不到header 加上header测试 ...
- 阶段5 3.微服务项目【学成在线】_day07 课程管理实战_06-课程营销实战分析
课程营销信息包括课程价格.课程有效期等信息. 课程营销信息使用course_market表存储. 接口我们要提供两个. 接口1先查询课程营销的信息,在页面展示. 接口2:叫做更新,如果发现数据不存在就 ...
- Qt编写自定义控件41-自定义环形图
一.前言 自定义环形图控件类似于自定义饼状图控件,也是提供一个饼图区域展示占比,其实核心都是根据自动计算到的百分比绘制饼图区域.当前环形图控件模仿的是echart中的环形图控件,提供双层环形图,有一层 ...
- Mysql5.7数据库介绍
(1).默认数据库介绍 information_schema 这个数据库保存了Mysql服务器所有数据库的信息.如数据库名.数据库的表.表栏的数据类型访问权限等. mysql 这个库是系统库,里面保存 ...
- 【Leetcode_easy】705. Design HashSet
problem 705. Design HashSet 题意: solution1: class MyHashSet { public: /** Initialize your data struct ...
- 【Leetcode_easy】682. Baseball Game
problem 682. Baseball Game solution: 没想到使用vector! class Solution { public: int calPoints(vector<s ...
- charles 批量重复请求/重复发包工具
本文参考:charles 批量请求 重复发包工具/repeat Charles 让你选择一个请求并重复,在测试后端接口的时候非常有用: Charles将请求重新发送到服务器,并将响应显示为新请求. 如 ...