Python垃圾回收

python采用引用计数法进行垃圾回收

Python内存分配

  • python在分配内存空间时,在malloc之上堆放了3个独立的分层。
  • python内存分配时主要由arena、pool和block三个构成。

第0层

  • 该层指glibc的malloc()这样的分配器,是对OS申请内存的部分。
  • python中如果生成的对象大于256B直接调用malloc,否则直接通过第1、2层分配。

第1层

  • 该层主要管理arena,arena大小固定为256KB,其中保存了arena中开头的pool的地址。
  • 同时保持被分配的pool的数量、将空pool连接到单向链表的功能。
  • arena是被数组arenas管理。
  • unused_arena_objects单向链表连接未使用的arena,包括新生的或使用过但已废弃的。
  • usable_arenas双链表,其中arena分配了可利用的pool。

第2层

  • 该层主要管理pool中的block,大小固定为4KB,每个pool的开头地址按照4KB的倍数对齐,与OS的页重合。
  • 在arena中将各个pool相连接。
  • pool被分隔成一个个的block,在pool初始化时就决定了该pool内的block的大小,block的大小是8B的整数倍,最大不超过256B。
  • Python分配时使用Best-fit,分配的block的大小最接近申请大小。
  • usedpools是保持pool的数组,每个pool用双向链表相连,数组中第一个位置中的是8B的pool集合直到第32个位置中的256B的pool。
  • 当usedpools中的pool的所有block被释放给arena。
  • block包括已经分配、使用完毕和未使用三种状态,后两者均可以将对象分配进去。
  • pool中定义了freeblock空闲表,用于链接使用完毕的block,而未使用的则在pool开头的nextoffset记录已分配的偏移。

分配

  • 根据申请的大小找到usedpools的索引。
  • 当usedpools中指定索引的pool被分配了则从pool中freeblock尝试获取block,不行则通过偏移取出block,如果pool内没有能分配的block则将pool从usedpools中移除。
  • 如果没有block则通过new_arena将新的arena添加到usable_arensa中,如果分配失败则调用malloc。
  • 初始化pool,从arena的freepools中获取一个pool插入到usedpools的开头,而后检查pool固定block大小与申请的block大小是否相同,如果不同则还需要初始化pool

释放

  • 将释放对象的block连接到freeblock。
  • 当pool内无已经分配的pool则将该pool连接到arena的freepools同时从usedpools中移除。
  • 当arena为空,从usable_arena移除,连接到unused_arena_objects中。
  • 当arena只有一个空pool时,即之前所有pool均被使用此时释放了一个pool,因此需要加入到usable_arenas。
  • usable_arenas内按照空pool的数量从小到大进行排序。usedpools也是优先使用被利用最多的pool。

对象特有的分配器

  • python中各种类型的对象持有各自的分配器。
  • 不同的对象拥有不同的空闲链表(数组),使用完毕的对象初始化后加入到该链表。
  • 如果空闲链表满了则直接释放。

引用计数

  • 对象内部有个计数器,32位环境下为int型,64位环境下为long型,指针为4的倍数因此使用这个长度还能多出两位。

循环引用垃圾回收

  • 对象链表(双向链表)连接各个对象,对象的引用计数器复制到自对象内的另一个位置。
  • 对复制的计数器中非根直接引用的减1。
  • 将对象分为可能到达的对象的链表,复制计数器大于1或有从活动对象的引用。
  • 将其余对象放如不可能到达的对象的链表,这些对象即是循环引用垃圾。
  • 容器对象:可能保留了指向其他对象的运用的对象
  • 循环引用的对象只可能出现在容器对象,可以将容器对象用对象链表连接。
  • 分代容器对象链表,分为3代,每代有个阈值,超过该阈值则进行该代的回收。同时每回收一次进行晋升一次。

《垃圾回收的算法与实现》——Python垃圾回收的更多相关文章

  1. Python垃圾回收机制--完美讲解!

    转自: http://www.jianshu.com/p/1e375fb40506 先来个概述,第二部分的画述才是厉害的. Garbage collection(GC) 现在的高级语言如java,c# ...

  2. python垃圾回收机制与小整数池

    python垃圾回收机制 当引用计数为0时,python会删除这个值. 引用计数 x = 10 y = x del x print(y) 10 引用计数+1,引用计数+1,引用计数-1,此时引用计数为 ...

  3. python垃圾回收机制:引用计数 VS js垃圾回收机制:标记清除

    js垃圾回收机制:标记清除 Js具有自动垃圾回收机制.垃圾收集器会按照固定的时间间隔周期性的执行. JS中最常见的垃圾回收方式是标记清除. 工作原理 当变量进入环境时,将这个变量标记为"进入 ...

  4. python 垃圾回收

    # 垃圾回收 # 小整数对象池 # a = 100# python对小整数的定义是[-5,257],这些证书对象是提前创建好的,不会被垃圾回收,再一个python的程序中,所有位于这个范围内的正式使用 ...

  5. python垃圾回收

    python垃圾回收 python垃圾回收主要使用引用计数来跟踪和回收垃圾.在引用计数的基础上,通过“标记—清除”解决容器对象可能产生的循环引用问题,通过“分代回收”以空间换时间的方法提高垃圾回收效率 ...

  6. python垃圾回收机制(Garbage collection)

    由于面试中遇到了垃圾回收的问题,转载学习和总结这个问题. 在C/C++中采用用户自己管理维护内存的方式.自己管理内存极其自由,可以任意申请内存,但也为大量内存泄露.悬空指针等bug埋下隐患. 因此在现 ...

  7. python 垃圾回收详解

    原文:https://zhuanlan.zhihu.com/p/31150408 总纲 策略和垃圾回收系统工作内容 引用计数详解 标记-清除+分代收集 循环引用 编程应用-常见方法 ex 过程详解 使 ...

  8. python垃圾回收算法

    标准python垃圾回收器由两部分组成,即引用计数回收器和分代垃圾回收器(即python包中的gc module).其中,引用计数模块不能被禁用,而GC模块可以被禁用. 引用计数算法 python中每 ...

  9. python 垃圾回收笔记

    目录 引用计数 python内部的引用计数机制 循环引用 调试内存泄漏 总结 python 程序在运行的时候,需要在内存中开辟出一块空间,用于存放运行时产生的临时变量:计算完成后,再将结果输出到永久性 ...

随机推荐

  1. SQL常用增删改查

    转 http://www.cnblogs.com/daxueshan/p/6687521.html 1增 1.1[插入单行]insert [into] <表名> (列名) values ( ...

  2. 1045 Favorite Color Stripe 动态规划

    1045 Favorite Color Stripe 1045. Favorite Color Stripe (30)Eva is trying to make her own color strip ...

  3. 笔记 Bioinformatics Algorithms Chapter1

    Chapter1 WHERE IN THE GENOME DOES DNA REPLICATION BEGIN    一. ·聚合酶启动结构域会结合上游序列的一些位点,这些位点有多个,且特异,并且分布 ...

  4. PHP与Python哪个做网站产品好?

    虽然python现在比较火,但在传统的LAMP组合里Linux+apache/tomcat+MySql+PHP里是PHP做网站的脚本语言,但现在已经变了:https://baike.baidu.com ...

  5. Codeforces822 C. Hacker, pack your bags!

    C. Hacker, pack your bags! time limit per test 2 seconds memory limit per test 256 megabytes input s ...

  6. Codeforces812A Sagheer and Crossroads 2017-06-02 20:41 139人阅读 评论(0) 收藏

    A. Sagheer and Crossroads time limit per test 1 second memory limit per test 256 megabytes input sta ...

  7. 第80讲:List的泛型分析以及::类和Nil对象

    今天我们学习一下scala中的列表,List. 通过源码,我们可以发现,List类型是协变的,所以我们可以把Int类型的List赋值给Any型的List. 我们可以看到,List定义下有3个比较重要的 ...

  8. hdu 4920

    http://acm.hdu.edu.cn/showproblem.php?pid=4920 给定两个n阶矩阵,求矩阵相乘后模3. 直接搞肯定会超时 特殊处理1和2的情况 实际上是水过的..... 貌 ...

  9. JVM的參數

    博客:https://www.cnblogs.com/redcreen/archive/2011/05/04/2037057.html#CMSInitiatingOccupancyFraction_v ...

  10. bootstrap3文章

    <!DOCTYPE html><html> <head> <meta charset="UTF-8"> <meta name= ...