当创建对象时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. Wpf使用Winform控件后Wpf元素被Winform控件遮盖问题的解决

    有人会说不建议Wpf中使用Winform控件,有人会说建议使用Winform控件在Wpf下的替代方案,然而在实际工作中由于项目的特殊需求,考虑到时间.成本等因素,往往难免会碰到在WPF中使用Winfr ...

  2. bzoj 1820 dp

    最普通dp要4维,因为肯定有一个在上一个的位置,所以可以变为3维,然后滚动数组优化一下. #include<bits/stdc++.h> #define LL long long #def ...

  3. JS图片滚动代码(无缝、平滑)

    非常平滑的JS图片滚动特效代码,无缝循环,速度可自定义,鼠标悬停时停止.它的特点是JS和图片地址分离,这样做你就经易的从数据库动态调用每张图片的地址,方便控制,因此它非常的应用. <!DOCTY ...

  4. 统计无向图中三角形的个数,复杂度m*sqrt(m).

    统计无向图中三角形的个数,复杂度m*sqrt(m). #include<stdio.h> #include<vector> #include<set> #inclu ...

  5. 让Xcode8.0支持iOS11.2设备真机测试

    最新支持11.2 (15C5097c)! 11.1 全版本! Xcode只可以支持iPhone手机对应iOS系统以下的真机测试.一般想要支持最新的iPhone手机系统,有两个方法. 第一.就需要更新X ...

  6. Web应用扫描工具Wapiti

    Web应用扫描工具Wapiti   Wapiti是Kali Linux预置的一款Web应用扫描工具.该工具执行黑盒扫描,用户只需要输入要扫描的网址即可.该工具可以探测文件包含.数据库注入.XSS.CR ...

  7. 掩码计算工具netmask

    掩码计算工具netmask   在网络扫描和防火墙配置中,经常需要计算IP地址范围和对应的掩码.为了简化这个过程,Kali Linux预置了一个掩码计算工具netmask.该工具不仅可以根据IP地址范 ...

  8. 深入理解Python生成器(Generator)

    我们可以通过列表生成式简单直接地创建一个列表,但是受到内存限制,列表容量肯定是有限的.而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,而且如果我们仅仅需要访问前面几个元素,那后面绝大多 ...

  9. AtCoder Grand Contest 019 F-yes or no

    AtCoder Grand Contest 019 F-yes or no 解题思路: 考虑一个贪心策略,假设当前还有 \(x\) 道 \(\text{yes}\) 和 \(y\) 道 \(\text ...

  10. BZOJ 1975: [Sdoi2010]魔法猪学院 大水题 第k短路 spfa

    https://www.lydsy.com/JudgeOnline/problem.php?id=1975 我好像到现在了第k短路都不会写,mdzz. 先spfa求出最短路,然后扫点存各种前置路径已经 ...