Python的内存管理和垃圾回收
内存管理
与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的内存管理和垃圾回收的更多相关文章
- python的内存管理与垃圾回收机制学习
一.python内存申请: 1.python的内存管理分为六层:最底的两层有OS控制.第三层是调用C的malloc和free等进行内存控制.第四层第五层是python的内存池.最上层使我们接触的直接对 ...
- Python的内存管理和垃圾回收机制
内存管理 Python解释器由c语言开发完成,py中所有的操作最终都由底层的c语言来实现并完成,所以想要了解底层内存管理需要结合python源码来进行解释. 1. 两个重要的结构体 include/o ...
- Python 内存管理与垃圾回收
Python 内存管理与垃圾回收 参考文献:https://pythonav.com/wiki/detail/6/88/ 引用计数器为主标记清除和分代回收为辅 + 缓存机制 1.1 大管家refcha ...
- Java内存管理和垃圾回收
笔记,深入理解java虚拟机 Java运行时内存区域 程序计数器,线程独占,当前线程所执行的字节码的行号指示器,每个线程需要记录下执行到哪儿了,下次调度的时候可以继续执行,这个区是唯一不会发生oom的 ...
- 面试题之C# 内存管理与垃圾回收
面试题之C# 内存管理与垃圾回收 你说说C# 的内存管理是怎么样的 这句话我记了一个多礼拜了, 自从上次东北师大面试之后, 具体请看<随便扯扯东北师大的面试>. 国庆闲着没事, 就大概了解 ...
- Java内存管理及垃圾回收总结
概述 Java和C++的一个很重要的差别在于对内存的管理.Java的自己主动内存管理及垃圾回收技术使得Java程序猿不须要释放废弃对象的内存.从而简化了编程的过程.同一时候也避免了因程序猿的疏漏而导致 ...
- C#内存管理与垃圾回收
垃圾回收还得从根说起,就像生儿育女一样. 根:根是一个位置,存放一个指针,该指针指向托管堆中的一个对象,或是一个空指针不指向任何对象,即为null.根存在线程栈或托管堆中,大部分的跟都在线程栈上,因为 ...
- 使用虚幻引擎中的C++导论(四-内存管理与垃圾回收)(终)
使用虚幻引擎中的C++导论(四)(终) 第一,这篇是我翻译的虚幻4官网的新手编程教程,原文传送门,有的翻译不太好,但大体意思差不多,请支持我O(∩_∩)O谢谢. 第二,某些细节操作,这篇文章省略了,如 ...
- Java之美[从菜鸟到高手演变]之JVM内存管理及垃圾回收
很多Java面试的时候,都会问到有关Java垃圾回收的问题,提到垃圾回收肯定要涉及到JVM内存管理机制,Java语言的执行效率一直被C.C++程序员所嘲笑,其实,事实就是这样,Java在执行效率方面确 ...
随机推荐
- 如何增加Tomcat内存
有时候在开发中,常常遇到内存溢出问题,很有可能项目过大,导致Tomcat内存不足问题,那么此时就要给Tomcat添加内存了,如,操作如下 1. 先找到Tomcat目录下的catalina.bat文件
- DataAnalysis-Pandas分组聚合
title: Pandas分组聚合 tags: 数据分析 python categories: DataAnalysis toc: true date: 2020-02-10 16:28:49 Des ...
- PHP获取当天、本周、本月、本季度、本年度时间
function get_date($date, $t = 'd', $n = 0) { if ($t == 'd') { $firstday = date('Y-m-d 00:00:00', str ...
- foreach-- for循环的增强型:for(类型 变量 : 数组对象) { 使用变量 }
/* * foreach:增强for循环,一般用于遍历集合或者数组 * 格式: * for(元素的类型 变量 : 集合或者数组对象) { * 可以直接使用变量; * } 注意:在增强for循环中不能修 ...
- AJ学IOS 之微博项目实战(13)发送微博调用相机里面的图片以及调用相机
AJ分享,必须精品 一:效果 二:代码 相机部分就简单多了,几行代码调用而已,但是如果你要是想实现更多丰富的功能,需要自己写.利用AssetsLibrary.framework,利用这个框架可以获得手 ...
- spring源码阅读笔记08:bean加载之创建bean
上文从整体视角分析了bean创建的流程,分析了Spring在bean创建之前所做的一些准备工作,并且简单分析了一下bean创建的过程,接下来就要详细分析bean创建的各个流程了,这是一个比较复杂的过程 ...
- U - Obtain a Permutation CodeForces - 1294E 思维
题解: 注意每一列与每一列之间互不影响,所以贪心地求出没一列的最小操作值,然后累加起来. 怎么求没一列的最小值呢?维护一个数组same表示其中same[i]=j表示将该序列向上翻滚i次有j个元素归位, ...
- 百度api实现人脸对比
第一步(注册账号): 点这里注册百度云账号 如图: 创建应用得到 APP_ID API_KEY SECRET_KEY 第二步(代码): import requests import base64 ...
- 4. js
1.) ~ 操作符 console.log(~-2) // 1 console.log(~-1) // 0 console.log(~0) // -1 console.log(~1) // ...
- react-i8n
1. 在项目中安装 npm install react-intl --save 2.兼容Safari各个版本需要安装intl npm install intl --save 3.编写语言包 1.)新建 ...