当创建对象时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. 【LOJ】#2065. 「SDOI2016」模式字符串

    题解 按秩合并怎么清数组对我来说真是世纪性难题 我们很熟练地想到点分,如果我们认为某个点到重心是正着读的,由于它的深度固定,它的串也是固定的,我们只要预处理出所有长度正着重复的串,反着重复的串,和它们 ...

  2. USACO 5.5 Picture

    PictureIOI 1998 A number, N (1 <= N < 5000), of rectangular posters, photographs and other pic ...

  3. hdoj1233 还是畅通工程(Prime || Kruskal)

    题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=1233 思路 最小生成树问题,使用Prime算法或者Kruskal算法解决. 代码 Prime算法: # ...

  4. 搭建 Android 集成开发环境

    在搭建 Android 集成开发环境之前,我想说的是,我们学习的目标是同时掌握移动开发三种方式:iOS开发.Android开发和Html5手机网页开发.由于iOS的开发工具是采用苹果官方的XCode, ...

  5. thinkphp 5.0如何实现自定义404(异常处理)页面

    404页面是客户端在浏览网页时,由于服务器无法正常提供信息,或是服务器无法回应,且不知道原因所返回的页面.404承载着用户体验与SEO优化的重任.404页面通常为用户访问了网站上不存在或已删除的页面, ...

  6. Java 关于集合框架那点事儿

     1.引入集合框架  采用数组存在的一些缺陷:   1.数组长度固定不变,不能很好地适应元素数量动态变化的情况.   2.可通过数组名.length获取数组的长度,却无法直接获取数组中真实存储的个数. ...

  7. 选择排序之C++实现

    选择排序之C++实现 一.源代码:SelectSort.cpp /* 选择排序(从小到大)的基本思想是,首先,选出最小的数,放在第一个位置: 然后,选出第二小的数,放在第二个位置: 以此类推,直到所有 ...

  8. 拆分Cocos2dx渲染部分代码

    纹理实现 思想 这个是Cocos2dx的渲染部分的最基本的实现,被我拆分到mac上,但是并不是用的EGLContext,而是搭配glfw,还有soil第三方图形库. 实现 // // main.cpp ...

  9. Codeforces Round #360 (Div. 2) B. Lovely Palindromes 水题

    B. Lovely Palindromes 题目连接: http://www.codeforces.com/contest/688/problem/B Description Pari has a f ...

  10. wikioi 1380 没有上司的舞会 树形dp

    1380 没有上司的舞会 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond       题目描述 Description Ural大学有N个职员,编号为1~N.他 ...