内存管理

与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. C语言变长数组

    #include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct Variable ...

  2. js及jquery常用插件

    1.backstretch背景图片插件 可实现背景自适应效果 <script src="dist/js/lib/backstretch/jquery.backstretch.min.j ...

  3. AJ学IOS 之小知识iOS启动动画_Launch Screen的运用

    AJ 分享,必须精品 看下效果吧 例如新浪微博的软件开启时候 就是这个 用Launch image实现 这个不难,就是在Images.xcassets 增加一个LaunchImage文件(右键 new ...

  4. ASE课程总结 by 林建平

    设想和目标 1. 我们的软件要解决什么问题?是否定义得很清楚?是否对典型用户和典型场景有清晰的描述? 我们的辅助用户在阅读英文文献时记忆生词,提高用户的生词量,减少用户的阅读障碍.定义非常清晰,要有查 ...

  5. 74HC595芯片的特性及使用方法和点评

    一 它能干什么?   74HC595是一个8位串行输入.平行输出的位移缓存器:平行输出为三态输出.在SCK的上升沿,单行数据由SDL输人到内部的8位位移缓存器,并由Q7‘输出,而平行输出则是在LCK的 ...

  6. G - Messy codeforces1262C

    题目大意: 输入n和m,n是n个字符,m是m个前缀.对前缀的规定可以配对的括号.比如(),,((()))等等.在输入n个括号字符,对这个n个字符,通过交换使其满足m个前缀.交换次数不限,规则想当与re ...

  7. Unity 游戏框架搭建 2019 (三十、三十一) MenuItem 显示顺序问题 & 类的提取

    在上一篇,我们得出了两个核心的学习思路: 根据问题去学习,并收集. 主动学习,并思考适用场景. 我们今天解决 MenuItem 显示顺序问题. 目前 MenuItem 显示如图所示: 我们来看下 Me ...

  8. (转载)基于BIGINT溢出错误的SQL注入

    我对于通过MySQL错误提取数据的新技术非常感兴趣,而本文中要介绍的就是这样一种技术.当我考察MySQL的整数处理方式的时候,突然对如何使其发生溢出产生了浓厚的兴趣.下面,我们来看看MySQL是如何存 ...

  9. C# WCF的通信模式

    wcf 通信模式一般分为三种; 1,请求/响应模式 2,单工模式 3,双工模式 一,请求/响应模式 请求/响应通信是指客户端向服务端发送消息后,服务端会向客户端发送响应.这也意味着在接收到服务的响应以 ...

  10. Java中基础类基础方法(学生类)(手机类)

    学生类: //这是我的学生类class Student { //定义变量 //姓名 String name; //null //年龄 int age; //0 //地址 String address; ...