首先我们要说是 以引用计数为主 标记清楚和分代回收为辅

接下来分以下几个方面解释

一 引用计数

每个对象内部都维护了一个值,该值记录这此对象被引用的次数,如果次数为0,则Python垃圾回收机制会自动清除此对象。下图是Python源码中引用计数器存储的代码。

引用计数器的获取及代码示例:

import sys

# 在内存中创建一个字符串对象"对子哈特",对象引用计数器的值为:1

nick_name = '对子哈特'

# 原则应该输出1,但是实际输出2,因为getrefcount方法时把 nick_name 当做参数传递了,引发引用计数器+1,所以打印时值为:2

# 注意:getrefcount 函数执行完毕后,会自动-1,所以本质上引用计数器还是1.

print(sys.getrefcount(nick_name))

# 变量 real_name 也指向的字符串对象"对子哈特",即:引用计数器再 +1,所以值为:2

real_name = nick_name

# 原则应该输出2,但是实际输出3. 因为getrefcount方法时把 real_name 当做参数传递了,引发引用计数器+1,所以打印时值为:3

# 注意:getrefcount 函数执行完毕后,会自动-1,所以本质上引用计数器还是2.

print(sys.getrefcount(nick_name))

# 删除reald_name变量,并让其指向对象中的引用计数器-1

del real_name

# 原则应该输出1,但是实际输出2,因为getrefcount方法时把 real_name 当做参数传递了,引发引用计数器+1,所以打印时值为:2.

print(sys.getrefcount(nick_name))

# ############ getrefcount 注释信息 ############

'''

def getrefcount(p_object): # real signature unknown; restored from __doc__

"""

getrefcount(object) -> integer

Return the reference count of object. The count returned is generally

one higher than you might expect, because it includes the (temporary)

reference as an argument to getrefcount().

"""

return 0

返回对象的引用计数。返回的计数一般是一个比您预期的要高,因为它包含(临时的)作为getrefcount()的参数引用。

'''

二 循环引用

通过引用计数器的方式基本上可以完成Python的垃圾回收,但它还是具有明显的缺陷,即:“循环引用”。

import gc

import objgraph

class Func(object):

def __init__(self):

self.data = None

# 在内存创建两个对象,即:引用计数器值都是1

obj1 = Func()

obj2 = Func()

# 两个对象循环引用,导致内存中对象的应用+1,即:引用计数器值都是2

obj1.data = obj2

obj2.data = obj1

# 删除变量,并将引用计数器-1。

del obj1

del obj2

# 关闭垃圾回收机制,因为python的垃圾回收机制是:引用计数器、标记清除、分代回收 配合已解决循环引用的问题,关闭他便于之后查询内存中未被释放对象。

gc.disable()

# 至此,由于循环引用导致内存中创建的obj1和obj2两个对象引用计数器不为0,无法被垃圾回收机制回收。

# 所以,内存中Foo类的对象就还显示有2个。

print(objgraph.count('Func'))

注意:gc.collect() 可以主动触发垃圾回收;

循环引用的问题会引发内存中的对象一直无法释放,从而内存逐渐增大,最终导致内存泄露。

为了解决循环引用的问题,Python又在引用计数器的基础上引入了标记清除和分代回收的机制。

so,不必再担心循环引用的问题了。

Reference cycles involving lists, tuples, instances, classes, dictionaries, and functions are found.

三 标记清除和分代回收

Python中每创建一个对象都会将对象放到一个双向链表中,每个对象中都有 _ob_next 和 _ob_prev 指针,用于挂靠到链表中

/* Nothing is actually declared to be a PyObject, but every pointer to

* a Python object can be cast to a PyObject*. This is inheritance built

* by hand. Similarly every pointer to a variable-size Python object can,

* in addition, be cast to PyVarObject*.

*/

typedef struct _object {

_PyObject_HEAD_EXTRA # 双向链表

Py_ssize_t ob_refcnt;

struct _typeobject *ob_type;

} PyObject;

typedef struct {

PyObject ob_base;

Py_ssize_t ob_size; /* Number of items in variable part */

} PyVarObject;

/* Define pointers to support a doubly-linked list of all live heap objects. */

#define _PyObject_HEAD_EXTRA \

struct _object *_ob_next; \

struct _object *_ob_prev;

随着对象的创建,该双向链表上的对象会越来越多。

当对象个数超过 700个 时,Python解释器就会进行垃圾回收。

当代码中主动执行 gc.collect() 命令时,Python解释器就会进行垃圾回收。

import gc

gc.collect()

Python解释器在垃圾回收时,会遍历链表中的每个对象,如果存在循环引用,就将存在循环引用的对象的引用计数器 -1,同时Python解释器也会将计数器等于0(可回收)和不等于0(不可回收)的一分为二,把计数器等于0的所有对象进行回收,把计数器不为0的对象放到另外一个双向链表表(即:分代回收的下一代)。

关于分代回收(generations):

The GC classifies objects into three generations depending on how many collection sweeps they have survived. New objects are placed in the youngest generation (generation 0). If an object survives a collection it is moved into the next older generation. Since generation 2 is the oldest generation, objects in that generation remain there after a collection. In order to decide when to run, the collector keeps track of the number object allocations and deallocations since the last collection. When the number of allocations minus the number of deallocations exceeds threshold0, collection starts. Initially only generation 0 is examined. If generation 0 has been examined more than threshold1 times since generation 1 has been examined, then generation 1 is examined as well. Similarly, threshold2 controls the number of collections of generation 1 before collecting generation 2.

# 默认情况下三个阈值为 (700,10,10) ,也可以主动去修改默认阈值。

import gc

gc.set_threshold(threshold0[, threshold1[, threshold2]])

python中垃圾回收机制_python 垃圾回收机制相关推荐

  1. python 内存回收机制_Python垃圾回收机制是什么

    不同于C/C++,像Python这样的语言是不需要程序员写代码来管理内存的,它的GC(Garbage Collection)机制 实现了自动内存管理.GC做的事情就是解放程序员的双手,找出内存中不用的 ...

  2. python实现链表的删除_Python垃圾回收机制

    python作为一门解释型语言,以代码简洁易懂著称.我们可以直接对名称赋值,而不必声明类型.名称类型的确定.内存空间的分配与释放都是由python解释器在运行时进行的.python这一自动管理内存功能 ...

  3. python 类定义 垃圾_什么是python对象摧毁?python中的对象摧毁(垃圾回收)机制是什么?...

    在这篇文章之中我们来了解一下python对象摧毁(垃圾回收),对于刚刚接触到python这一编程语言的朋友来说,对于python对象摧毁(垃圾回收)的了解应该比较少,并且不清楚关于python垃圾回收 ...

  4. python垃圾回收价格表_Python垃圾回收机制详解

    一.垃圾回收机制 Python中的垃圾回收是以引用计数为主,分代收集为辅.引用计数的缺陷是循环引用的问题. 在Python中,如果一个对象的引用数为0,Python虚拟机就会回收这个对象的内存. #e ...

  5. python中if的效率_Python 代码性能优化技巧

    选择了脚本语言就要忍受其速度,这句话在某种程度上说明了 python 作为脚本的一个不足之处,那就是执行效率和性能不够理想,特别是在 performance 较差的机器上,因此有必要进行一定的代码优化 ...

  6. python内存管理机制_python内存管理机制

    python内存管理机制: 引用计数 垃圾回收(引用计数,标记清除,分带回收) 内存池 1. 引用计数 当一个python对象被引用时 其引用计数增加 1 ; 当其不再被变量引用时 引用计数减 1 ; ...

  7. python中doc=parased.getroot()_python实例手册.py

    python实例手册 #encoding:utf8 # 设定编码-支持中文 0 说明 手册制作: 雪松 littlepy www.51reboot.com 更新日期: 2016-01-21 欢迎系统运 ...

  8. [转载] python中pass的使用_Python pass详细介绍及实例代码

    参考链接: Python pass语句 Python pass详细介绍及实例代码 Python pass的用法: 空语句 do nothing 保证格式完整 保证语义完整 以if语句为例,在c或c++ ...

  9. python中的cell函数_python基础-函数

    函数的基本使用 函数的参数详解 名称空间与作用域 闭包函数 装饰器 2020.9.11 小白学习,如有错误欢迎指点 参考自egon大佬Python快速入门神器​www.zhihu.com 函数 使用函 ...

最新文章

  1. selenium提取数据之driver对象的常用属性和方法
  2. 090901 T 面试中遇到的一个Sql Question
  3. 在window平台运行Dubbo的一个小demo
  4. 好用的 php类,一个好用的php文件上传处理类
  5. POJ 2516 基础费用流
  6. 计算机网络访问控制列表,南昌大学计算机网络实验-访问控制列表ACL
  7. CUDA编程之快速入门-----GPU加速原理和编程实现
  8. 各种流行编程语言的优缺点
  9. 【Kafka】kafka Removed ✘✘✘ expired offsets in ✘✘✘ milliseconds.
  10. Linux目录结构详解
  11. Unity 镜子反射特效
  12. 锐捷(四)交换机虚拟化(VSU)+双主机检测(BFD)的配置
  13. linuxpv操作实验_操作系统实验三:Linux进程管理及其扩展
  14. openjudge 买书
  15. 国防科技大学计算机专业戴眼镜,国防科技大学的男生毕业照流出,被女网友们狂赞:“把我扔进去”...
  16. 有意思的hand-crafted features based IQA的论文吧(图像质量评价)
  17. matlab定义双精度型变量_MATLAB小数(浮点数)类型
  18. 据说要改变Web3应用层,X2Earn又是什么?
  19. 搜狗搜索事业部总经理:从识图搜索谈未来大势
  20. tensorflow 1.13.1 requires wheel>=0.26, which is not installed. After October 2020 you may exper

热门文章

  1. beautifulsoup解析动态页面div未展开_Python爬虫 | 0xb 数据解析:PyQuery库
  2. 第10章 随机山水画(《Python趣味创意编程》教学视频)
  3. mysql怎么拿到一个表里的所有列名字
  4. java形状函数_java基础:10.4 Java FX之形状
  5. java 抽象类、接口使用
  6. 微软拆分 VS Code 中 Python 扩展,部分功能可独立下载
  7. 被弃用的 Docker 未死:带着 1.05 亿美元融资“回归”,估值高达 21 亿
  8. 用技术谱写美好生活,「亚马逊云科技线上黑客松2021」报名开启!
  9. 256 变 4096:分库分表扩容如何实现平滑数据迁移?
  10. 通过代码学 Sutton 强化学习:SARSA、Q-Learning 时序差分算法训练 CartPole