当创建对象时Python立即向操作系统请求内存。每当对象的引用数减为0,Python垃圾回收器立刻挺身而出,立即将其释放,把内存还给操作系统。
在Python中,每个对象都保存了一个称为引用计数的整数值,来追踪到底有多少引用指向了这个对象。无论何时,如果我们程序中的一个变量或其他对象引用了目标对象,Python将会增加这个计数值,而当程序停止使用这个对象,则Python会减少这个计数值。一旦计数值被减到零,Python将会释放这个对象以及回收相关内存空间。而对于创建的对象,无论存在循环引用与否,只有还在使用,没有被释放,就会慢慢的随着分代的策略,慢慢进入2代(老年代)

通过频繁的处理零代链表中的新对象,Python的垃圾收集器将把时间花在更有意义的地方:它处理那些很快就可能变成垃圾的新对象。同时只在很少的时候,当满足阈值的条件,收集器才会去处理那些老变量。这种算法的根源来自于弱代假说(weak generational hypothesis):这个假说由两个观点构成:首先是年轻的对象通常死的也快,而年老对象则很有可能存活更长的时间。

引用计查看方法:sys.getrefcount?,在ipython里使用问号查看帮助信息

In [17]: sys.getrecursionlimit?
Docstring:
getrecursionlimit()

Return the current value of the recursion limit, the maximum depth
of the Python interpreter stack.  This limit prevents infinite
recursion from causing an overflow of the C stack and crashing Python.
Type:      builtin_function_or_method

In [18]:

hex(id(a))查看是否真的被回收

感觉 标记-清除 与 分代可以看成一个整体
标记-清除过程先从零代开始,清理最频繁的也是零代,然后是第一代、第二代

Python中的循环引用总是发生在container对象之间, 所谓containser对象即是内部可持有对其他对象的引用: list/dict/class/instance等等,不会是int str
"标记-清除"是为了解决循环引用的问题.可以包含其他对象引用的容器对象(比如:list,set,dict,class,instance)都可能产生循环引用

新创建的对象都在0代,0代不被引用计数和标记清除算法回收的对象会被放入1代,1代不被引用计数和标记清除算法回收的对象会被放入2代

gc.get_threshold
gc.set_threshold正确理解,默认值[700,10,10]
0代的700表示新创建的对象超过700个则对0代进行垃圾回收,能回收的回收掉,不能回收的放到1代中。1代的默认阈值10表示记录0代进行回收的次数,即0代回收次数超过10次,则对1代进行垃圾回收,能回收的回收,不能回收的放入2代;2代的10表示1代回收的次数阈值,当1代回收次数超过10次时,对2代进行回收,能回收的回收,不能回收的继续放到2代里,等待下一次回收。每一代回收完,就会变化值0

gc.collect()对所有代进行回收,回收完,恢复gc.get_count()的次数(0,0,0)
gc.get_count()返回0代创建对象的个数即当前已经发生回收的次数,比如(10,9,5)表示当前新建的对象10个,还没有经过分代回收,而已经发生回收9*5=45次

python2没有这个函数gc.get_stats()返回0、1、2代各自的(还未回收的数量,已经进行垃圾回收的次数,不可以回收的对象)
In [16]: gc.get_stats()
Out[16]:
[{'collected': 16564, 'collections': 333, 'uncollectable': 0},
 {'collected': 2373, 'collections': 27, 'uncollectable': 0},
 {'collected': 119, 'collections': 10, 'uncollectable': 0}]

执行一次gc.collect(0),则gc.get_count()的第2个值即1代的值加1,表示进行了一次0代回收
执行一次gc.collect(1),则gc.get_count()的第3个值即2代的值加1,同时第2个值即1代的值变为0,表示进行了一次1代回收
执行一次gc.collect(2),则gc.get_count()的第3个值即2代的值变为0,表示进行了一次2代回收

小对象:int、str并不会创建对象,所有使用list,dict、tuple等;str/int有个地址池,这类小对象的创建不体现在计数里,所以gc.get_count()[0]里体现不出变化
验证的时候使用python3.7的编译环境,不要使用ipython这种环境

gc.set_threshold正确理解,默认值[700,10,10]:7000*10*10=70000

开启debug和gc.enable():gc.set_debug(gc.DEBUG_STATS|gc.DEBUG_COLLECTABLE)

示例:
执行下面的的语句,创建10W个对象,你会发现有100+次0代垃圾回收,10+次1代回收,1次2代垃圾回收,证明:是根据频次来计算的
以python3测试为主:
python里的批量创建对象的方法:locals()

for i in range(100000):
  locals()['str'+str(i)]={'a':i}

或者稍微大点的对象:
for i in range(100000):
  locals()['strwo'+str(i)]={'a':{'b':str(i)},'xx':{'wo':str(i)+'0代的700表示新创建的对象超过700则对0代进行垃圾回收,能回收的回收   ,不能回收的放到1代中。1代的默认阈值10表示记录0代进行回收的次数,即0代回收次数超过10次,则对1代进'}}

参考:
https://foofish.net/python-gc.html
https://juejin.im/post/5b34b117f265da59a50b2fbe

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垃圾回收

    Python垃圾回收 python采用引用计数法进行垃圾回收 Python内存分配 python在分配内存空间时,在malloc之上堆放了3个独立的分层. python内存分配时主要由arena.po ...

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

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

  8. python 垃圾回收详解

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

  9. python垃圾回收算法

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

随机推荐

  1. wampserver的安装和使用

    首先想说一下通常搭建WAMP平台的时候主要分为散装包搭建和集成包搭建过程. 散装包搭建就是把PHP,Apache,MySQL等下载下来,一个个的安装,其过程灰常的复杂,而且需要配置的系统变量和修改的文 ...

  2. python中发送邮件各种问题

    其实问题主要集中的QQ企业邮箱中,特别坑爹...代码如下: from email.mime.multipart import MIMEMultipart from email.mime.base im ...

  3. hdoj1879 继续畅通工程(Prime || Kruskal)

    题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=1879 思路 这题和hdoj1102很像,图中的有一些路已经修好了,对于这些已经修好的路,我们令还需要修 ...

  4. Tuning Optimization

    2017-02-22 在经过Trace的分析并重新优化之后 CPU: Intel(R) Xeon(R) CPU E5-2630 v2 @ 2.6GHz 24core 如上图,CPU使用率平均低于60% ...

  5. 推荐:这才是你寻寻觅觅想要的 Python 可视化神器

    Plotly Express 是一个新的高级 Python 可视化库:它是 Plotly.py 的高级封装,它为复杂的图表提供了一个简单的语法. 受 Seaborn 和 ggplot2 的启发,它专门 ...

  6. 第二波分析:德国是2018世界杯夺冠最大热门? Python数据分析来揭开神秘面纱… (附源代码)

    2018年,世界杯小组赛已经在如火如荼的进行中.在上篇文章的基础上[2018世界杯:用Python分析热门夺冠球队],我们继续分析世界杯32强的实力情况,以期能够更进一步分析本次世界杯的夺冠热门球队. ...

  7. MongoDB复制原理

    ##mongodb复制(主从服务器数据备份, 一个主服务器可以有很多个从服务器) #mongodb的复制至少需要两个节点.其中一个是主节点,负责处理客户端请求,其余的都是从节点,负责复制主节点上的数据 ...

  8. 「HNOI2018」游戏

    「HNOI2018」游戏 解题思路 首先没有锁上的门可以缩点缩掉,然后对于一扇锁上的门,如果钥匙在左边,那么右边就永远不可能到达左边,同理如果钥匙在右边,左边就永远不可能到达右边. 然后考虑一个暴力的 ...

  9. 【SPFA】POJ1511-Invitation Cards

    [题目大意] 给出一张有向图,以1位源点,求“从源点出发到各点的距离”和“与各点返回源点的距离和”相加得到的和. [思路] 毫无疑问是最短路径,但是这数据量就算是SPFA也绝壁会超时啊,抱着必死的心态 ...

  10. 【洛谷】3469:[POI2008]BLO-Blockade【割点统计size】

    P3469 [POI2008]BLO-Blockade 题意翻译 在Byteotia有n个城镇. 一些城镇之间由无向边连接. 在城镇外没有十字路口,尽管可能有桥,隧道或者高架公路(反正不考虑这些).每 ...