Python中的内存管理---引用计数与垃圾收集

Python中的内存管理 Python中的内存管理 内存是一本空白的书 可以将计算机的内存想像成一本用来写短篇小说的空书。它的页面上还没有任何的内容,但是到了后面,不同的作者将会出现。每个作者都想要一些空间来书写它们的内容。 由于它们不允许书写在不属于它们的页,因此它们必须小心写内容在页面上,在它们开始写作之前,它们会咨询负责管理这本书的“经理”,然后由经理来决定允许它们写书的位置。 由于这本书已经存在了很长的时间,所以其... 阅读详情

1. CPython介绍

Python 是一种解释型编程语言。你的 Python 代码实际上被编译成更多计算机可读的指令,称为字节码 (即我们经常在 __pycache__ 文件夹中见到的 .pyc 文件)。当您运行代码时,这些指令由虚拟机解释。

默认的 Python 实际上是CPython,  是用 C 编写的,运行时由它解释 Python 字节码。除 CPython 之外还有其他实现

常见python解释器
名称CPythonIronPythonJythonPyPy
语言CC#JavaPython

本文我只介绍由 Python 的默认实现 CPython 完成的内存管理.  在Python中, 一切都是对象, (甚至 int, str 这些数据类型也是对象), 但是C语言本身不支持 OOP (面向对象编程), CPython的实现中, 有一个 struct 叫做 PyObject,CPython 中的每个其他对象都使用它。

Python中的所有对象都可以理解为是 PyObject 的子类. PyObject只包含2个内容

  1. ob_refcnt : 引用计数
  2. ob_type: 指向实际对象类型的指针

ob_type 指向的类型, 是另一种 C struct, 它描述一个Python 对象 (例如 str 或 list). 每个对象都有一个内存分配器和释放器, 用于获取和释放内存.

2. 垃圾收集

前面提到, Python 中的每个对象都有一个引用计数和一个指向类型的指针。当对象的引用计数为 0 时, Python 解释器就会从内存中将该对象删除. 

2.1 引用计数的增加与减少

以下3种行为会使得对象的引用增加

  1. 被分配给一个变量
  2. 被作为参数传递
  3. 被包含在其他可变对象中, 如列表和字典

可以使用sys模块中的getrefcount方法检查对象的当前引用计数, 将对象作为参数传递给getrefcount方法会增加引用计数1

In [1]: import sys

In [2]: a = [1, 2]  # 列表[1, 2] 赋值给变量a, 引用计数为 1
In [3]: sys.getrefcount(a)  # a 作为参数传给函数, 引用计数+1, 为2
Out[3]: 2

In [4]: b = a # 列表[1, 2] 赋值给变量b, 引用计数+1 
In [5]: sys.getrefcount(a)
Out[5]: 3

In [6]: dct = {'key': a} # a 包含在字典lst中, 引用计数+1
In [7]: sys.getrefcount(a)
Out[7]: 4

 与引用计数增加的行为相反,  删除变量可以使引用计数减少

In [8]: del dct
In [9]: sys.getrefcount(a)
Out[9]: 3

In [10]: del b
In [11]: sys.getrefcount(a)   
Out[11]: 2   

# getrefcount函数将引用计数+1, 函数执行完毕后 a 的引用计数为 1
In [10]: del a  # a的引用计数为0, 内存中释放列表[1, 2]对象

3. 避免写入冲突--GIL

可以把计算机的内存理解为一个笔记本, 不同的进程就是不同的作者, 大家可以共同在笔记本中书写和擦掉自己的内容. 如果不同的作者都在同一页笔记本写数据, 整个页面相互叠加, 双方的内容都变得不可读.

CPython的解决方案是增加一个全局解释器锁 GIL (Global Interpreter Lock),  GIL 通过锁定整个解释器使得同一时刻, 只有一个线程可以拥有解释器锁, 避免了内存冲突. 可以把 GIL 理解为一跟公用的笔,  同一时刻只能有一个作者能申请使用笔来写入笔记. 

另一个原因是, 上文提到垃圾收集依赖于对象的引用计数. 引用计数变量需要避免被两个线程同时增加或减少其值. 例如如下代码, 此时列表 [1] 的引用计数为2.  

 b = a = [1]

若两个进程同时执行 del b 和 del a , 2个进程获取的引用计数都是2, 将其 -1 之后, 引用计数还是1. 造成内存泄漏, 对象 [1] 永远停留在内存中, 直到Python解释器结束. 

总结

CPython中, 对所有对象维护一个引用计数, 一旦下降到0, 将对象从内存中删除.

CPython依赖全局解释器锁来避免内存冲突.

Python源码之内存管理机制(二)---垃圾回收机制 文章目录1、引用计数1.1 循环引用问题2、三色标记机制3、垃圾收集机制3.1 对象集合--双向链表3.2 分代回收机制3.3 标记-清除机制3.3.1 寻找root object的集合3.3.2 垃圾标记3.3.3 垃圾回收4、垃圾收集机制总结 1、引用计数   在之前的文章中我们都有看到各种与引用计数相关的东西,Python和Java,c#一样也在语言层面实现了动态的内存管理机制,这一点我们很清楚,这就意味着我们从繁琐的手动内存管理中解放了,将内存的释放和各种管理交给Python自己完成,我们可以看到在 阅读详情

相关推荐

别再为模糊的3D重建头疼了!手把手教你用3DSlicer处理DICOM数据,搞定医学影像三维可视化

本文详细解析了医学影像三维重建中常见的模糊问题,并手把手教你使用3DSlicer处理DICOM数据,实现精准的三维可视化。从层厚设置到数据格式转换,再到重建算法选择和渲染参数微调,提供了一套完整的优化方案,特别适合临床医生和医学影像处理人员提升工作效率。

weixin_28693447的博客 247

python多线程详解 Python 垃圾回收机制

python多线程详解 一、线程介绍 什么是线程 线程(Thread)也叫轻量级进程,是操作系统能够进行运算调度的最小单位,它被包涵在进程之中,是进程中的实际运作单位。线程自己不拥有系统资源,只拥有一点儿在运行中必不可少的资源,但它可与同属一个进程的其它线程共享进程所拥有的全部资源。一个线程可以创建和撤消另一个线程,同一进程中的多个线程之间可以并发执行。 为什么要使用多线程 线程在程序中是独立的、...

小小小麦昆的博客 2689

weblogic启动异常故障处理(boot认证失败)

root 用户生成的文件属主为 root,WebLogic进程将无权读取,直接导致认证失败。· ⚠️ 密码必须完全一致:第3步 AdminAccount 命令中设置的密码,与第5步所有 boot.properties 文件中 password= 字段的值,必须保证完全一致。如果您的域下配置了受管服务器实例(如 ms_server1、ms_server2 等),必须逐一更新各实例下的免密启动文件,确保实例重启时密码与AdminServer保持一致,否则实例启动会因认证失败而报错。此步骤至关重要,必须执行。

weixin_53389944的博客 221

python的是如何做内存管理的

gc会记录自从上次收集以来新分配的对象数量与释放的对象数量,当两者之差超过threshold0的值时,gc的扫描就会启动,初始的时候只有世代0被检查。当某对象的引用计数值为0,那么它的内存就会被立即释放掉。我们定义变量会申请内存空间来存放变量的值,而内存的容量是有限的,当一个变量值没有用了(简称垃圾)就应该将其占用的内存给回收掉,而变量名是访问到变量值的唯一方式,所以当一个变量值没有关联任何变量名时,我们就无法再访问到该变量值了,该变量值就是一个垃圾会被Python解释的垃圾回收机制自动回收。...

weixin_69061187的博客 515

Zabbix华为交换机光衰告警

zabbix使用自动发现监控huawei网络设备光衰

qq_31651649的博客 4529

LC-3 机器语言 指令集

生活本就沉闷,但跑起来就有风

笔记 1万+

Python的内存管理以及垃圾回收

参考:http://www.cnblogs.com/CBDoctor/p/3781078.html 先从较浅的层面来说,Python的内存管理机制可以从三个方面来讲 (1)垃圾回收 (2)引用计数 (3)内存池机制 一、垃圾回收: python不像C++,Java等语言一样,他们可以不用事先声明变量类型而直接对变量进行赋值。对Python语言来讲,对象的类型

Mr.Yan的专栏 2万+

CentOS 7 安装 Python 3.10

我这里已经软链接了,正常未链接之前是python->python2.7而不是python3.10。python2.7默认安装是在 /usr/bin目录中,切换到/usr/bin/更改yum配置,因为其要用到python2才能执行,否则会导致yum不能正常使用。2. 安装 Python 3.10 必需的 openssl >= 1.1.1。默认的centos7是没有安装pip,先添加epel扩展源。/usr/bin/python 修改为如下。添加软链接,将原来的链接备份。添加python3的软链接。

bensonyang888的博客 2905

python计数_Python的引用计数

在我所接触到的语言虚拟机中,使用引用计数法进行对象回收的,只有Python,我这节课就介绍一下Python的垃圾回收机制,以及使用Python进行编程时要注意的一些地方。前边的课程就介绍过了,我们这个课程虽然聚焦在Java,但遇到和其他语言相通的地方,或者是可以相互借鉴的地方,也会介绍一些其他语言的知识。本节课的内容与Java没有任何关系,如果只对Java语言感兴趣,而对Python等其他语言没什...

weixin_39819283的博客 199

无人机开发平台全解析:从开源飞控到企业级应用实战指南

无人机开发平台是无人机从飞行器演变为智能空中机器人的核心,其本质是提供了一套标准化的软硬件接口与工具链,使开发者能够基于稳定可靠的底层系统,专注于上层应用创新。从技术原理上看,一个完整的开发平台通常包含飞行控制器、机载计算机、传感器套件等硬件层,以及飞控固件、机器人操作系统(ROS/ROS 2)、软件开发套件(SDK)等软件层,通过分层架构实现飞行控制、感知决策与任务执行的解耦。其技术价值在于大幅降低了无人机行业应用的开发门槛,使开发者无需从零构建飞行控制系统,即可快速实现自动巡检、精准农业、物流配送等复杂

weixin_28712491的博客 412

从零到一:YOLOv8在边缘设备上的轻量化部署实战

本文详细介绍了YOLOv8在边缘设备上的轻量化部署实战,涵盖模型优化、TensorRT加速、剪枝与知识蒸馏等关键技术。通过工业质检和智能门禁项目案例,展示了如何将YOLOv8高效部署到树莓派、Jetson Nano等资源受限设备,显著提升推理速度和降低内存占用。文章还提供了动态分辨率调整、多模型级联部署等实用技巧,助力开发者实现边缘AI应用的高效落地。

weixin_29040367的博客 379

Python笔记,内存管理(1)---引用计数

引用计数 在python中,每个对象都有存有该对象的引用总数,即引用计数(feference count) 引用计数原理 1.每个对象维护一个ob_ref减1,用来记录该对象当前被引用的次数 2.每当新的引用指向该对象时,它的引用计数ob_ref加1 3.每当该对象的引用失效时ob_ref减1 4.一旦对象的引用计数为0,该对象可以被回收,对象占用的内存空间将被释放 5.它的缺点是需要额外的空间维护计数,这个问题是其次的 6.最主要的问题是它不能解决对象的“循环引用” 获取引用计数.getrefcount(

weixin_49750432的博客 2253

modelsim软件安装教程及踩坑(极简版)

1.安装的网盘链接:链接:https://pan.baidu.com/s/1ltUfssyXlCnqDmLhWyhlwA提取码:jery 2.步骤(参考博文):https://blog.youkuaiyun.com/weixin_42693097/article/details/90523692?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522163521788716780357213801%2522%252C%2522scm%2522%253A%2522

subtitle_的博客 3780

Python 垃圾收集

Python 是最流行的编程语言之一,其使用量还在不断增长。由于其增长率,它在 2021 年的TIOBE 年度语言中排名第三。Python 的易用性和庞大的社区使其成为数据分析、Web 应用程序和任务自动化的流行选择。 在这篇文章中,我们将详细介绍 Python 中的垃圾收集。首先,我们将回顾有关内存管理的基础知识以及我们为什么需要垃圾回收。然后我们将看看 Python 是如何实现垃圾收集的。最后,我们将实际看看在编写 Python 应用程序时应该如何考虑垃圾收集。 什么是 Pyt...

allway2的博客 416

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

Python的垃圾回收机制

通常情况下,在Python中并不需要进行内存管理,当对象不再被需要的时候,Python会自动回收这些对象占用的内存空间。但是了解垃圾回收器(Garbage Collector, GC)是如何工作的,有助于写出更好、运行更高效的Python程序。不同于很多其它语言,Python并不是必须要将对象占用的内存释放给操作系统。取而代之的是,Python中有一个专用的对象分配器(object allocator),专门用于给小于512字节的对象分配内存,这个分配器可以将这些对象驻留在内存中,以便未来用到的时候可以快速

ikkyphoenix的专栏 1289

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

Python的内存管理

在 Python 中,内存管理涉及到一个包含所有 Python 对象和数据结构的私有堆(heap)。这个私有堆的管理由内部的 Python 内存管理器(Python memory manager) 保证。Python 内存管理器有不同的组件来处理各种动态存储管理方面的问题,如共享、分割、预分配或缓存。内存管理机制python3.6.9 内存管理的官方文档。

weixin_46247191的博客 1669

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

python怎么清理垃圾_python清理内存

广告关闭腾讯云11.11云上盛惠 ,精选热门产品助力上云,云服务器首年88元起,买的越多返的越多,最高返5000元!语言的内存管理是语言设计的一个重要方面。 它是决定语言性能的重要因素。 无论是c语言的手工管理,还是java的垃圾回收,都成为语言最重要的特征。 这里以python语言为例子,说明一门动态类型的、面向对象的语言的内存管理方式。 对象的内存使用赋值语句是语言最常见的功能了。 但即使是最...

weixin_39528289的博客 875

Python 核心编程笔记_Chapter_3 Note_3 内存管理_垃圾回收

想了想还是单独做一份关于内存管理的笔记,因为这个基础知识比较重要,而且自己没什么概念。 内存分配 作为一个负责任的程序员,我们知道在为变量分配内存时,是在借用系统资源,在用完之 后, 应该释放借用的系统资源。Python 解释器承担了内存管理的复杂任务, 这大大简化了应 用程序的编写。你只需要关心你要解决的问题,至于底层的事情放心交给Python 解释器去做就 行了。 3.5.

bestallen的博客 402

python对象的垃圾收集_浅析Python3中的对象垃圾收集机制

###概述 GC作为现代编程语言的自动内存管理机制,专注于两件事:1. 找到内存中无用的垃圾资源 2. 清除这些垃圾并把内存让出来给其他对象使用。 在Python中,它在每个对象中保持了一个计数器,用于记录指向该对象的的引用的个数。一旦这个计数器为0时,则立即回收该对象,对象占用的内存空间将被释放。引用计数我们可以利用简单的变量引用和销毁窥见引用计数过程。增加引用计数增加引用计数的方式多种,即对象...

weixin_39999536的博客 104

Python 高手编程系列六十二:引用计数

值得注意的例子是 PyTuple_GetItem()和 PyList_GetItem()。是为了解决引用计数(reference counting)算法中的循环引用的问题。SetItem()在 list[1]索引上设置新值时,之前存储在该索引处的对象的所有权会被处。由引用(PyObject*指针)表示的 Python 中的每个对象都有一个相关的引用计数。但在我们讨论它们的细节之前,我们需要了解更多关于引用所有权的术语。调用 PyObject_Print(),并引用不再存在的对象。

2401_86113894的博客 759

24 | 带你解析 Python 垃圾回收机制

今天这节课,我们深入了解了 Python 的垃圾回收机制,主要强调下面这几点:1. 垃圾回收是 Python 自带的机制,用于自动释放不会再用到的内存空间;2. 引用计数是其中最简单的实现,不过切记,这只是充分非必要条件,因为循环引用需要通过不可达判定,来确定是否可以回收;3. Python 的自动回收算法包括标记清除和分代收集,主要针对的是循环引用的垃圾收集;4. 调试内存泄漏方面, objgraph 是很好的可视化分析工具。

qq_37756660的博客 908

【Python系列】Python 中的垃圾收集:深入理解与实践

????????????欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。推荐:kwan 的首页,持续学习,不断总结,共同进步,活到老学到老导航 檀越剑指大厂系列:全面总结 java 核心技术,jvm,并发编程 redis,kaf...

weixin_34552443的博客 133

深入理解Python中的循环引用和垃圾回收

weakref模块允许开发者创建对对象的弱引用,这意味着即使存在弱引用,对象的引用计数也不会增加。当对象的引用计数降到0时,即使存在弱引用,对象也会被垃圾回收。一些常用的内存分析工具包括objgraph等。这些工具可以帮助开发者可视化内存使用情况,识别循环引用,并提供内存泄漏的诊断信息。循环引用是Python编程中一个常见的问题,它会导致内存泄漏和性能问题。通过理解Python的垃圾回收机制,我们可以更好地管理和优化内存使用。使用weakref。

无远弗届 1602

Python 高手编程系列二千零六十二:引用计数

值得注意的例子是 PyTuple_GetItem()和 PyList_GetItem()。是为了解决引用计数(reference counting)算法中的循环引用的问题。SetItem()在 list[1]索引上设置新值时,之前存储在该索引处的对象的所有权会被处。由引用(PyObject*指针)表示的 Python 中的每个对象都有一个相关的引用计数。但在我们讨论它们的细节之前,我们需要了解更多关于引用所有权的术语。调用 PyObject_Print(),并引用不再存在的对象。

2301_77888392的博客 804

Python 高手编程系列二千一百六十二:引用计数

值得注意的例子是 PyTuple_GetItem()和 PyList_GetItem()。是为了解决引用计数(reference counting)算法中的循环引用的问题。SetItem()在 list[1]索引上设置新值时,之前存储在该索引处的对象的所有权会被处。由引用(PyObject*指针)表示的 Python 中的每个对象都有一个相关的引用计数。但在我们讨论它们的细节之前,我们需要了解更多关于引用所有权的术语。调用 PyObject_Print(),并引用不再存在的对象。

2301_77888392的博客 619

python info函数_深挖Python的内存管理机制:垃圾回收机制

Python 程序在运行时,需要在内存中开辟出一块空间,用于存放运行时产生的临时变量,计算完成后,再将结果输出到永久性存储器中。但是当数据量过大,或者内存空间管理不善,就很容易出现内存溢出的情况,程序可能会被操作系统终止。而对于服务器这种用于永不中断的系统来说,内存管理就显得更为重要了,不然很容易引发内存泄漏。这里的内存泄漏是指程序本身没有设计好,导致程序未能释放已不再使用的内存,或者直接失去了对...

weixin_39852688的博客 257
上一篇: Python 如何写干净的代码 Clean-Code
下一篇: Python 并发编程(二) GIL (全局解释器锁)
be5yond
博客等级 码龄10年 590粉丝 123原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值