标记清除:
- 标记清除算法作为Python的辅助垃圾收集技术主要处理的是一些容器对象,比如list、dict、tuple,instance等,因为对于字符串、数值对象是不可能造成循环引用问题。
- Python使用一个双向链表将这些容器对象组织起来。
- 缺点:清除非活动的对象前它必须顺序扫描整个堆内存,哪怕只剩下小部分活动对象也要扫描所有对象。
引用计数:
当指向该对象的内存的引用计数器为0的时候,该内存将会被Python虚拟机销毁
-
该对象的引用计数器+1:
- 对象被创建 a=1
- 对象被引用 b=a
- 对象被作为参数,传到函数中 func(a)
- 对象作为一个元素,存储在容器中 List={a,”a”,”b”,2}
-
该对象的引用计数器-1:
- 当该对象的别名被显式销毁时 del a
- 当该对象的引别名被赋予新的对象, a=2
- 一个对象离开它的作用域,例如 func函数执行完毕时,函数里面的局部变量的引用计数器就会减一(但是全局变量不会)
- 将该元素从容器中删除时,或者容器被销毁时。
- 优点:高效、实时、平摊处理时长、易于实现
- 缺点:消耗相应的计数资源、循环引用问题
分代回收:
主流程如下:
- 分配内存
- 发现超过阈值了
- 触发垃圾回收
- 将所有可收集对象链表放到一起
- 遍历, 计算有效引用计数
- 分成 有效引用计数=0 和 有效引用计数 > 0 两个集合
- 大于0的, 放入到更老一代
- =0的, 执行回收
- 回收遍历容器内的各个元素, 减掉对应元素引用计数(破掉循环引用)
- 执行-1的逻辑, 若发现对象引用计数=0, 触发内存回收
- python底层内存管理机制回收内存
分代回收是一种以空间换时间的操作方式,Python将内存根据对象的存活时间划分为不同的集合,每个集合称为一个代,Python将内存分为了3“代”,分别为年轻代(第0代)、中年代(第1代)、老年代(第2代),他们对应的是3个链表,它们的垃圾收集频率与对象的存活时间的增大而减小。新创建的对象都会分配在年轻代,年轻代链表的总数达到上限时,Python垃圾收集机制就会被触发,把那些可以被回收的对象回收掉,而那些不会回收的对象就会被移到中年代去,依此类推,老年代中的对象是存活时间最久的对象,甚至是存活于整个系统的生命周期内。同时,分代回收是建立在标记清除技术基础之上。分代回收同样作为Python的辅助垃圾收集技术处理那些容器对象
版权声明:本文为weixin_42225318原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。