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在执行效率方面确 ...
随机推荐
- 搭建环境-git常见使用总结
Descripton:git 一.Git安装和本地用户全局配置 官网下载并且安装 查看是否安装成功win + R输入git,出现git命令指南,则安装成功 全局配置本地用户,在git Bash中进行下 ...
- HAproxy shell脚本安装
#!/bin/bash #需要lua-..tar.gz在家目录下 # 编译安装lua #安装编译环境需要的包 yum -y install gcc openssl-devel pcre-devel s ...
- node实现防盗链
什么是防盗链 盗链,顾名思义就是盗窃链接,就是在他人未经允许的情况下,去使用他人站点的任何图片,视频,内容等资源,来借此提升已用的站点的活跃度,严重损坏了别人的利益.那么防盗链就是采用一些办法阻止自己 ...
- Python实战---制作专属有声小说(调用百度语音合成接口)
这一次的目标是使用百度云的人工智能接口,实现文字转语音的实时转换,将小说文字转换成语音朗读出来. 百度云接口调用 百度的这个接口对于我们普通用户非常友好,他的很多功能都是免费的,而且我们每天可以免费调 ...
- Volatile不保证原子性(二)
Volatile不保证原子性 前言 通过前面对JMM的介绍,我们知道,各个线程对主内存中共享变量的操作都是各个线程各自拷贝到自己的工作内存进行操作后在写回到主内存中的. 这就可能存在一个线程AAA修改 ...
- python3 xlwt,csv学习
前言 对于抓取一些站点分析然后指纹识别的时候可能用到到它.所以学习下.这里就记录一些最基本的感觉有用的. xlwt 基本创建 demo: #coding=utf- import xlwt yunyin ...
- shiro:注解配置(五)
基于[shiro集成spring]项目改造 引入相关依赖环境 <!--AOP的jar包--> <dependency> <groupId>org.aspectj&l ...
- SpringCloud-Hystrix 服务降级、熔断
Hystrix 是什么? Hystrix 是一个用于处理分布式系统的延迟和容错的开源库,在分布式系统里,许多依赖不可避免的会调用失败,比如超时.异常等,Hystrix 能够保证在一个依赖出问题的情况下 ...
- .NET Core 3 WPF MVVM框架 Prism系列之对话框服务
本文将介绍如何在.NET Core3环境下使用MVVM框架Prism的对话框服务,这也是prism系列的最后一篇完结文章,下面是Prism系列文章的索引: .NET Core 3 WPF MVVM框 ...
- 用SQL查询分析实现类似金蝶K3的收发存明细表
使用SQL查询分析实现类收发存的报表,原始需求在 另外一篇文章 的第四部分.下图是实现需求. 一.准备 删除临时表 [buy]判断是否存在临时表,存在则删除[/buy] if OBJECT_ID('t ...