python 内存管理

Python中的内存管理涉及包含所有Python对象和数据结构的私有堆。Python内存管理器在内部确保对此私有堆的管理。需要注意的是,Python堆的管理是由解释器本身执行的,并且用户无法控制它。从源码来看,分为以下几层:

python 内存管理架构

  • level +3:内置类型分配器
  • level +2:python对象分配器
  • level +1:python原生内存分配器
  • level   0:底层通用分配器
  • level -1:特定于os的虚拟内存管理器
  • level -2:物理内存管理器

由上可知,Python 中的对象管理主要位于 +1 ~ +3 层。对于大于512KB(可以设置更改)的对象,使用 +1层中的 Python 原生内存分配器(Python’s raw memory allocator)进行分配,其本质是调用 C 标准库中的 malloc/calloc/realloc/free等函数;对于小于等于 512KB 的对象,使用+2层的Python 对象分配器(Python’s object allocator)实施。对于一些内置类型,如 int/dict/list/string 等,会有单独的针对这些内置类型的分配器实现。比如管理 int 类型就使用一个简单的 free list,这些分配器都位于 +3层。

在Python中,为了解决内存泄露问题,采用了对象引用计数(reference count),并基于引用计数实现自动垃圾回收。借助“标记-清除”机制消除循环引用带来的影响。引入“分代回收”机制减少“标记-清除”所带来的额外操作。

  • 引用计数
# 计数增加  refcnt incr
#define Py_INCREF(op) (
_Py_INC_REFTOTAL _Py_REF_DEBUG_COMMA
((PyObject*)(op))->ob_refcnt++)
#计数减少   refcnt desc
#define _Py_DEC_REFTOTAL _Py_RefTotal--
#define _Py_REF_DEBUG_COMMA ,
#define Py_DECREF(op)do{if(_Py_DEC_REFTOTAL _Py_REF_DEBUG_COMMA
--((PyObject*)(op))->ob_refcnt!= 0)
_Py_CHECK_REFCNT(op)else
_Py_Dealloc((PyObject *)(op));          # refcnt变成0的时候, 会调用_Py_Dealloc}while(0)PyAPI_FUNC(void)_Py_Dealloc(PyObject *);#define _Py_REF_DEBUG_COMMA ,
#define _Py_Dealloc(op) (_Py_INC_TPFREES(op)_Py_COUNT_ALLOCS_COMMA
(*Py_TYPE(op)->tp_dealloc)((PyObject *)(op)))         # 调用各自类型的tp_dealloc
#endif /* !Py_TRACE_REFS */
# Python基本类型的tp_dealloc, 通常都会与各自的缓冲池机制相关,释放会优先放入缓冲池中(对应的分配会优先从缓冲池取).这个内存分配与回收同缓冲池机制相关
# 当无法放入缓冲池时, 会调用各自类型的tp_free
# 当计数变为0时,使用tp_free函数进行内存销毁的操作
PyTypeObject PyType_Type= {
PyVarObject_HEAD_INIT(&PyType_Type,0)
"type",                 /* tp_name */
...
PyObject_GC_Del,        /* tp_free */
};
  • 内存回收
    • 放入缓冲池:缓存部分反复创建和销除的对象,而非在它们释放后直接从内存删除它们,从而加速下次该对象的创建。
    • 真正销毁,使用PyObject_Del/PyObject_GC_Del对内存进行操作
      • PyObject_Del  不运行析构函数只释放内存。同PyObject_Free
      • PyObject_GC_Del

void
PyObject_GC_Del(void*op)
{
PyGC_Head *g= AS_GC(op);
# 如果跟踪给定对象,则返回true
if(IS_TRACKED(op))                 # IS_TRACKED 涉及标记-清除机制
# 从跟踪链表中移除
gc_list_remove(g);
if(generations[0].count> 0){       # generations 涉及分代回收机制
generations[0].count--;
}
PyObject_FREE(g);                  # PyObject_FREE 涉及python底层内存池机制
}
  • 标记-清除
  • 分代回收
    • 将系统中的所有内存块根据其存活时间划分为不同的集合, 每个集合就称为一个”代”。
    • 一个代就是一个链表, 所有属于同一”代”的内存块都链接在同一个链表中。
    • Python中总共有三个”代”,每个代的threshold值表示该代最多容纳对象的个数。默认情况下,当0代超过700,或1,2代超过10,垃圾回收机制将触发。0代触发将清理所有三代,1代触发会清理1,2代,2代触发后只会清理自己。
    • 垃圾收集的频率随着”代”的存活时间的增大而减小(存活时间越长的对象, 就越不可能是垃圾, 就会减少其收集的频率)

  • id() 查看该对象的内存地址;
  • is 判断两个引用所指的对象是否相同;
  • sys包中的getrefcount()来查看对象的引用次数。需要注意的是,当使用某个引用作为参数,传递给getrefcount()时,参数实际上创建了一个临时的引用。因此,getrefcount()所得到的结果,会比期望的多1。

http://ju.outofmemory.cn/entry/215604

Python 源码阅读:垃圾回收机制

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/494667.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Matlab个性化绘图第6期—带标记面的三维折线图

带标记面的三维折线图本质上就是多组折线图: Matlab论文插图绘制模板第92期—折线图(Plot) 或者三维折线图: Matlab论文插图绘制模板第37期—三维折线图(plot3) 不同之处在于带标记面的三维折线图把每一组数据单独放在一个三维平…

C/C++圣诞树

系列文章 序号直达链接1C/C爱心代码2C/C跳动的爱心3C/C李峋同款跳动的爱心代码4C/C满屏飘字表白代码5C/C大雪纷飞代码6C/C烟花代码7C/C黑客帝国同款字母雨8C/C樱花树代码9C/C奥特曼代码10C/C精美圣诞树11C/C俄罗斯方块12C/C贪吃蛇13C/C孤单又灿烂的神-鬼怪14C/C闪烁的爱心15C…

【C++语言】多态

一、多态的概念 多态的概念:通俗来说,就是多种形态,具体点就是去完成某种行为,当不同的对象去完成时会产生出不同的状态。 我们可以举一个例子: 比如买票这种行为,当普通人买票时,是全价买票&am…

GitCode 光引计划投稿|MilvusPlus:开启向量数据库新篇章

在人工智能和大数据时代,向量数据库作为处理非结构化数据的核心技术,正变得越来越重要。MilvusPlus,作为「光引计划」的一部分,应运而生,旨在提供一个高性能、易扩展、全功能的向量数据库解决方案。项目背景根植于对现…

Java设计模式 —— 【结构型模式】外观模式详解

文章目录 概述结构案例实现优缺点 概述 外观模式又名门面模式,是一种通过为多个复杂的子系统提供一个一致的接口,而使这些子系统更加容易被访问的模式。该模式对外有一个统一接口,外部应用程序不用关心内部子系统的具体的细节,这…

Gin-vue-admin(1):环境配置和安装

目录 环境配置如果443网络连接问题,需要添加代理服务器 后端运行前端运行 环境配置 git clone https://gitcode.com/gh_mirrors/gi/gin-vue-admin.git到server文件目录下 go mod tidygo mod tidy 是 Go 语言模块系统中的一个命令,用于维护 go.mod 文件…

浅谈算法交易

本文想基于我的简单理解说说什么是算法交易,或者说是量化交易。 原文地址请访问:浅谈算法交易 什么是算法交易? 刚开始接触算法交易的时候,对它的理解,它就是把我平时的交易规则搬进计算机里自动执行。这个理解也没…

《点点之歌》“意外”诞生记

世界是“点点”的,“点点”是世界的。 (笔记模板由python脚本于2024年12月23日 19:28:25创建,本篇笔记适合喜欢诗文的coder翻阅) 【学习的细节是欢悦的历程】 Python 官网:https://www.python.org/ Free:大咖免费“圣经”教程《 …

项目代码第6讲:UpdownController.cs;理解 工艺/工序 流程、机台信息;前端的“历史 警报/工艺 记录”

一、UpdownController.cs 1、前端传入 当用户在下图的“记录查询”中的 两个界面选项 中,点击“导出”功能时,向后端发起请求,请求服务器下载文件的权限 【权限是在Program.cs中检测的,这个控制器里只需要进行“谁在哪个接口下载了文件”的日志记录】 【导出:是用户把…

Docker 技术系列之安装多版本Mysql5.6和Mysql5.7

image 大家好,后面的就不是关于MAC专有的内容,基本是跟Java环境,基础技术方面有关。所以这个教程对于在linux系统还是macOS都是通用的,不用担心。 上一篇,我们安装好对应的Docker之后,感受到了它的便利。接…

机器学习04-为什么Relu函数

机器学习0-为什么Relu函数 文章目录 机器学习0-为什么Relu函数 [toc]1-手搓神经网络步骤总结2-为什么要用Relu函数3-进行L1正则化修改后的代码解释 4-进行L2正则化解释注意事项 5-Relu激活函数多有夸张1-细数Relu函数的5宗罪2-Relu函数5宗罪详述 6-那为什么要用这个Relu函数7-文…

【GO环境安装】mac系统+GoLand使用

文章目录 下载安装包环境配置GoLandGo Modules 下载安装包 地址:GO下载地址 下载好后直接进行安装: 进入terminal,查看是否安装成功: 环境配置 在文稿下面创建工作目录: 在文稿下新建Go_Works文件夹,在…

京东大数据治理探索与实践 | 京东零售技术实践

01背景和方案 在当今的数据驱动时代,数据作为关键生产要素之一,其在商业活动中的战略价值愈加凸显,京东也不例外。 作为国内领先的电商平台,京东在数据基础设施上的投入极为巨大,涵盖数万台服务器、数 EB 级存储、数百…

Day13 苍穹外卖项目 工作台功能实现、Apache POI、导出数据到Excel表格

目录 1.工作台 1.1 需求分析和设计 1.1.1 产品原型 1.1.2 接口设计 1.2 代码导入 1.2.1 Controller层 1.2.2 Service层接口 1.2.3 Service层实现类 1.2.4 Mapper层 1.3 功能测试 1.4 代码提交 2.Apache POI 2.1 介绍 2.2 入门案例 2.2.1 将数据写入Excel文件 2.2.2 读取Excel文…

程控电阻箱应用中需要注意哪些安全事项?

程控电阻箱是一种用于精确控制电路中电流和电压的电子元件,广泛应用于电子实验、测试设备以及精密测量仪器中。在应用程控电阻箱时,为确保安全和设备的正常运行,需要注意以下几个安全事项: 1. 正确连接:确保电阻箱与电…

SQL server学习09-数据库编程(上)

目录 一,了解T-SQL语言 1,常量(标量值) 2,变量 1)局部变量 2)全局变量 二,内置函数 1,字符串函数 2,数学函数 3,日期时间函数 4&#x…

springboot中使用gdal将表中的空间数据转shapefile文件

springboot中使用gdal将表中的空间数据转shapefile文件 代码: // 样本导出-将样本表导出为shapefile,复制样本shp文件到临时目录下 sampleDir是文件夹pathpublic void setYbShapeFile(Yb yb, File sampleDir) {// 创建 前时项 和 后时项 文件夹File y…

0.96寸OLED显示屏详解

我们之前讲了 LCD1602,今天我们将它的进阶模块——OLED。它接线更少,性能更强,也能显示中文和图像了。 大家在学习单片机的时候是否会遇到调试的问题呢?例如 “这串代码我到底运行成功了没有” ,我相信很多刚开始学习…

MySQL数据库——复制表数据与结构

命令格式 create table 表名 select 字段1,字段2 from 被复制表 首先新建一个表,然后从被复制的表中选择字段复制到新表 举例

Zabbix6.0升级为7.2

Zabbix 7.0 进行了全新升级,本文讲解如何从 6.0 版本升级至最新版本 7.2。在 CentOS 8 上通过RPM 方式安装 Zabbix 服务 一、环境信息 我是CentOS 7安装的服务端,在该机器在通过源码去安装 Zabbix 7.0 版本的话,会比较费劲,因为有…