Python的垃圾回收机制详解

作者:Jeemzz 时间:2023-06-03 16:03:24 

引用计数

在Python源码中,每一个对象都是一个结构体表示,都有一个计数字段。


typedef struct_object {
 int ob_refcnt;
 struct_typeobject *ob_type;
} PyObject;

PyObject是每个对象必有的内容,其中ob_refcnt就是作为引用计数。当一个对象有了新的引用时,它的ob_refcnt就会增加,引用它的对象被删除时则减少。一旦对象的引用计数为0,该对象立即被回收,占用空间就会被释放。

优点

  • 简单易用

  • 实时性好,一旦没有引用就会被立即释放

缺点

  • 需要额外空间去维护引用计数

  • 不能解决对象的循环引用

对象的循环引用
循环引用是指两个对象相互引用且没有外部变量引用其中任何一个,导致引用链形成一个环。


>>> a = {}    # 对象a的引用计数为1
>>> b = {}    # 对象b的引用计数为1
>>> a['b'] = b  # b的引用计数增加1
>>> b['a'] = a  # a的引用计数增加1
>>> del a     # a的引用计数减少1,最后a的引用为1
>>> del b     # b的引用计数减少1,最后b的引用为1

在执行完del操作之后,没有任何引用指向a、b对象,但是由于这两个对象各自包含一个对对方的引用,所以引用计数始终保持在1。

按照引用计数中内存回收的原理,由于a和b的计数不为0,所以在使用引用计数法进行内存管理的时候这两个对象不会被回收,它们会一直驻留在内存中,造成内存泄露。

标记清除

标记清除机制主要用于解决循环引用问题。

标记清除算法是一种基于追踪回收(tracing GC)技术实现的垃圾回收算法。主要分为两个阶段:

  • 标记阶段,GC会将所有的活动对象打上标记

  • 对那些没有打上标记的非活动对象进行回收

区分活动对象与非活动对象

对象之间通过引用即指针连接在一起,构成一个有向图,对象就是这个有向图的节点,而引用关系构成这个有向图的边。从根对象(root object)出发,沿着有向边遍历对象,可达的对象会被标记为活动对象,不可达的对象就是要被清除的非活动对象。

根对象一般是全局变量、调用栈、寄存器等。

适用范围

标记清除算法作为Python辅助的垃圾收集技术,主要处理的是容器对象,因为对于字符串、数值对象等,不可能造成循环引用的问题,Python会使用一个双向链表将这些容器对象组织起来。

对于标记清除算法来说,有一个比较明显的缺点:为了清除非活动对象,需要扫描整个堆内存,哪怕只剩下小部分活动对象也需要扫描所有对象。

分代回收

分代回收是一种以空间换时间的操作方式,建立在标记清除技术的基础之上,也是Python辅助的垃圾收集技术,主要用于处理容器对象。

Python会将内存根据对象的存活时间划分为不同的集合,每个集合称为一个代,主要会被分为3代:年轻代。中年代和老年代,它们会对应3个链表,对应的垃圾收集频率随着对象存活时间的增大而减小。

新创建的对象都会被分配在年轻代,当年轻代链表总数达到上限时,会触发Python的垃圾回收机制,对可回收对象进行回收,而那些不可回收的对象会被移到中年代去。依此类推,老年代对象是存活时间最久的对象,甚至有可能存活在整个系统的生命周期内。

来源:https://www.cnblogs.com/jeemzz/p/11420725.html

标签:python,垃圾,回收,机制
0
投稿

猜你喜欢

  • 在javascript中,null>=0 为真,null==0却为假,null的值详解

    2024-04-25 13:08:52
  • JavaScript修改作用域外变量的方法

    2024-04-10 16:12:01
  • php将12小时制转换成24小时制的方法

    2023-11-21 15:56:08
  • python制作图片缩略图

    2023-08-23 18:49:32
  • PyQt5实现用户登录GUI界面及登录后跳转

    2021-04-08 07:50:03
  • python下函数参数的传递(参数带星号的说明)

    2022-12-20 02:58:59
  • vue自定义tap指令及tap事件的实现

    2024-05-09 09:25:15
  • MySql 5.7.17压缩包免安装的配置过程图解

    2024-01-27 20:02:14
  • python中upper是做什么用的

    2023-10-30 15:53:29
  • 用Python的urllib库提交WEB表单

    2023-06-11 00:14:52
  • 基于Django用户认证系统详解

    2023-04-13 15:35:13
  • python爬虫爬取淘宝商品比价(附淘宝反爬虫机制解决小办法)

    2021-11-14 06:16:40
  • Python使用socket模块实现简单tcp通信

    2021-04-20 14:54:14
  • Javascript 类型转换方法

    2024-04-10 10:51:21
  • 实现动画效果核心方式的js代码

    2024-04-19 10:45:39
  • MSSQL数据类型及长度限制详细说明

    2024-01-25 06:01:09
  • 记一次pyinstaller打包pygame项目为exe的过程(带图片)

    2023-12-29 12:45:19
  • 浅谈JavaScript窗体Window.ShowModalDialog使用

    2024-04-23 09:05:39
  • 利用python汇总统计多张Excel

    2023-12-31 14:22:11
  • tween.js缓动补间动画算法示例

    2024-05-21 10:13:40
  • asp之家 网络编程 m.aspxhome.com