内存管理

与Python对象创建相关的结构体

#define _PyObject_HEAD_EXTRA            \
struct _object *_ob_next; \
struct _object *_ob_prev; #define PyObject_HEAD PyObject ob_base; #define PyObject_VAR_HEAD PyVarObject ob_base; typedef struct _object {
_PyObject_HEAD_EXTRA // 用于构造双向链表
Py_ssize_t ob_refcnt; // 引用计数器
struct _typeobject *ob_type; // 数据类型
} PyObject; typedef struct {
PyObject ob_base; // PyObject对象
Py_ssize_t ob_size; /* Number of items in variable part,即:元素个数 */
} PyVarObject;

对Python内存管理理解

Python是由C语言开发。
Python中所有对象的创建均与C语言中的两个结构体有关,分别是Pyobject和PyVarobject。
在Python中创建由单个元素组成的对象时(比如float类型),会使用Pyproject结构体,在创建由多个元素组成的对象时,使用PyVarproject创建。
Pyobject内部维护了数据类型,引用计数器,和双向链表,PyVarproject内部比Pyobject多了一个元素个数。
在Python中,每创建一个对象,首先会开辟内存并对其进行初始化(引用计数器设为1),再将其对象添加到双向链表中(ref_chain)。
再对对象进行重复引用时,该对象的引用计数器(ob_refcnt)会增加1,删除变量时(del 变量)会找到该变量对应的对象的引用计数器进行减1操作,
如果计数器变为0,系统将会把该对象对应的内存作为垃圾(实际上会放到缓存链表free_list中,如果再次创建同类型(float和列表类型)数据时,不会重新开辟内存,就会把free_list中同类型的内存数据改变后,重新引用,减少了重新开辟内存的开销)。

验证回收后的内存会先放在free_list中:

会发现,删除float类型后,在创建float类型,不会重新开辟新内存。

垃圾回收

引用计数器为主,标记清除和分代回收为辅。

1:引用计数器:为零时作为垃圾回收。
2:标记清除:由于引用计数器无法解决循环引用的问题,多个元素组成的对象才可能造成循环引用。
Python底层会将Python中所有对象分类成为两个链表,分别是由单个元素和多个元素组成的对象,Python内部会定期扫描由多个元素组成对象的链表,如果遇到循环引用,则让各自的计数器减1,如果此时计数器变为零则变成垃圾。 3:分代回收:由于在标记清除扫描链表时,链表对象比较多,并且为了设置对象扫描的优先级,设置了分代回收,分别是0代,1代,2代。0代扫描十次,才会扫描1代一次,如果发现对象仍被引用,则进行升级,级别越高,成为垃圾的几率越小,扫描次数也越小,减少了系统扫描造成的资源消耗。
注:对象链表长度为700,扫描一次。

循环引用

a=[1,2]
b=[3,4] a.append(b) #a=[1,2,b]
b.append(a) #b=[3,4,a] del a
del b #del a b后,原a,b对应的引用计数器仍为1,因此会在内存中一直存在。

Python的内存管理和垃圾回收的更多相关文章

  1. python的内存管理与垃圾回收机制学习

    一.python内存申请: 1.python的内存管理分为六层:最底的两层有OS控制.第三层是调用C的malloc和free等进行内存控制.第四层第五层是python的内存池.最上层使我们接触的直接对 ...

  2. Python的内存管理和垃圾回收机制

    内存管理 Python解释器由c语言开发完成,py中所有的操作最终都由底层的c语言来实现并完成,所以想要了解底层内存管理需要结合python源码来进行解释. 1. 两个重要的结构体 include/o ...

  3. Python 内存管理与垃圾回收

    Python 内存管理与垃圾回收 参考文献:https://pythonav.com/wiki/detail/6/88/ 引用计数器为主标记清除和分代回收为辅 + 缓存机制 1.1 大管家refcha ...

  4. Java内存管理和垃圾回收

    笔记,深入理解java虚拟机 Java运行时内存区域 程序计数器,线程独占,当前线程所执行的字节码的行号指示器,每个线程需要记录下执行到哪儿了,下次调度的时候可以继续执行,这个区是唯一不会发生oom的 ...

  5. 面试题之C# 内存管理与垃圾回收

    面试题之C# 内存管理与垃圾回收 你说说C# 的内存管理是怎么样的 这句话我记了一个多礼拜了, 自从上次东北师大面试之后, 具体请看<随便扯扯东北师大的面试>. 国庆闲着没事, 就大概了解 ...

  6. Java内存管理及垃圾回收总结

    概述 Java和C++的一个很重要的差别在于对内存的管理.Java的自己主动内存管理及垃圾回收技术使得Java程序猿不须要释放废弃对象的内存.从而简化了编程的过程.同一时候也避免了因程序猿的疏漏而导致 ...

  7. C#内存管理与垃圾回收

    垃圾回收还得从根说起,就像生儿育女一样. 根:根是一个位置,存放一个指针,该指针指向托管堆中的一个对象,或是一个空指针不指向任何对象,即为null.根存在线程栈或托管堆中,大部分的跟都在线程栈上,因为 ...

  8. 使用虚幻引擎中的C++导论(四-内存管理与垃圾回收)(终)

    使用虚幻引擎中的C++导论(四)(终) 第一,这篇是我翻译的虚幻4官网的新手编程教程,原文传送门,有的翻译不太好,但大体意思差不多,请支持我O(∩_∩)O谢谢. 第二,某些细节操作,这篇文章省略了,如 ...

  9. Java之美[从菜鸟到高手演变]之JVM内存管理及垃圾回收

    很多Java面试的时候,都会问到有关Java垃圾回收的问题,提到垃圾回收肯定要涉及到JVM内存管理机制,Java语言的执行效率一直被C.C++程序员所嘲笑,其实,事实就是这样,Java在执行效率方面确 ...

随机推荐

  1. String 对象-->fromCharCode() 方法

    1.定义和用法 将ASCII码转换成对应的字符 语法: String.fromCharCode(n1, n2, ..., nX) 参数: n1, n2, ..., nX:一个或多个 Unicode 值 ...

  2. Array(数组)对象-->splice() 方法

    1.定义和用法 splice() 方法用于添加或删除数组中的元素. 语法: array.splice(index,howmany,item1,.....,itemX) 参数: index:该参数是开始 ...

  3. Linux U盘启动盘制作工具

    近期由于自己使用的ubuntu系统一直出问题,想做一下启动盘帮助恢复系统和故障检测,以前一直是用ultraiso来进行写盘的,但是发现制作了几次后,失败的机率很高,主要有以下几种情况: 1.引导有问题 ...

  4. [转] [知乎] Roguelite 和 Roguelike 的区别是什么?

    编者按 本文译自 Ethan Hawkes 一篇介绍 rogue-lite 概念的文章,已获作者授权,英文原文见这里,译文首发于这里.注意本文写于 2013 年,正是 roguelite 类型的独立游 ...

  5. 绝地求生模拟登陆!高难度JS解密教程,Python高级爬虫开发,

    前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. PS:如有需要Python学习资料的小伙伴可以加点击下方链接自行获取htt ...

  6. L5语言模型与数据集

    本次实验使用的数据下载: jaychou_lyrics.txt 链接:https://pan.baidu.com/s/1LJSrkpV84YF61OPmjIHGIw 提取码:dj53 语言模型 一段自 ...

  7. L3 多层感知机

    **本小节用到的数据下载 1.涉及语句 import d2lzh1981 as d2l 数据1 : d2lzh1981 链接:https://pan.baidu.com/s/1LyaZ84Q4M75G ...

  8. 实验一 熟悉IDLE和在线编程平台

    实验目的 1.掌握python IDLE集成开发环境的安装与使用 2.熟悉在线编程平台 3.掌握基本的python程序编写.编译与运行程序的方法 实验内容 1.按照实验指导安装IDLE,尝试交互式运行 ...

  9. B - Bash and a Tough Math Puzzle CodeForces - 914D (线段树的巧妙应用)

    题目大意:当输入2时,将p处的点的值修改为x, 当输入1时,判断区间[L,R]的gcd是否几乎正确,几乎正确的定义是最多修改一个数,使得区间[L,R]的gcd为x. 题解:用线段树维护一个gcd数组, ...

  10. 1324E - Sleeping Schedule

    题目大意:一天有h个小时,一个人喜欢睡觉,一共睡n次,每次都睡h个小时,开始时间为0,间隔a[i]或a[i]-1个小时开始睡第i次觉,每天都有一个最好时间区间,问这n次觉,最多有多少次是在最好时间内睡 ...