python进阶之垃圾回收

内存使用

程序在运行的过程需要开辟内存空间,比如创建一个对象需要一片内存空间,定义变量需要内存空间。有内存的开辟,势必也要有内存的释放,不然只进不出那不是貔貅了吗?即使有开辟有释放在短期内还是会有垃圾内存的存在。

内存管理

在有些语言中,内存的开辟和回收需要在代码中完成,典型的例子就是C语言。C语言中开辟一块内存:ptr=(int*)malloc(sizeof(int)*n); 释放一块内存:free(ptr);这个过程是需要写在内存使用之前的程序中的(没有轮子怎么办,咱们自己造)。而Java,Python这类语言内存的开辟和回收不需要代码实现,在后台中有专门负责内存回收的机制GC。

python中使用的垃圾回收机制有两个:

1.引用计数,标记清除

2.隔代回收

引用计数,标记清除

python里每一个东西都是对象,它们的核心就是一个结构体:PyObject

typedef struct_object {
    int ob_refcnt;
    struct_typeobject *ob_type;
} PyObject;

PyObject是每个对象必有的内容,其中ob_refcnt就是做为引用计数。当一个对象有新的引用时,它的ob_refcnt就会增加,当引用它的对象被删除,它的ob_refcnt就会减少

#define Py_INCREF(op)   ((op)->ob_refcnt++) //增加计数
#define Py_DECREF(op) \ //减少计数
if (--(op)->ob_refcnt != 0)      ; else      __Py_Dealloc((PyObject *)(op))

创建对象时Python立即向操作系统请求内存,同时Python将对象的C结构体里的 ob_refcnt 的值设为1。

如果对变量a重新赋值,此时变量a就会指向一个新的对象,新对象的引用数值为1,旧对象引用计数的值就会被置成0。

当python 的垃圾回收机制发现内存中的对象的计数引用值为0时,它就发现该自己闪亮登场了。垃圾回收机制会销毁该对象,释放内存。

引用计数,标记清除这一招是十分奏效的,可以解决大部分的对象回收。但是就是有那么一些情况是这一招解决不了的,那就是循环引用。所谓循环应用指的是两个对象互相引用,且成为了一个孤岛,没有别的对象关联。

这种情况下,引用计数值一直都是1,想要释放 ’tommorr‘ 不行,因为它被 ’another‘引用了,所以要先释放 ’another‘才能使用 ’tommor‘,但是’another‘又被tommorr引用,也无法释放。这该怎么办呢?这时需要python垃圾回收的第二个机制 隔代回收出马了。

隔代回收

隔代回收机制主要3板斧:

第一:所有创建的对象都会加入到零代链表中,并扫描零代链表中所有的循环引用。如图发现两个对象的循环引用。

第二:将发现的循环引用的引用计数都减1。

当循环引用计数值为0之后,就被标记清除,垃圾回收第一规则就生效。如果清除一次引用计数还不为0咋办呢?那就是第三步

第三步:将零代中引用计数不为0的对象加入到一代链表中,在一代链表中会重复零代中的循环计数减1操作。同时如果生命力顽强到一代链表都没处理的,那么会加入到二代链表。

以上讲到的是垃圾回收机制的大体思路,其实python的垃圾回收机制比以上描述的要复杂很多,很多深奥的东西可以看篇文章:https://www.cnblogs.com/pinganzi/p/6646742.html

原文地址:https://www.cnblogs.com/goldsunshine/p/11561612.html

时间: 2024-10-15 14:27:06

python进阶之垃圾回收的相关文章

Python中的垃圾回收机制

当我们声明一个对象的时候,例如str="abcdef",当我们不再使用str这个对象的时候,这个对象就是一个脏对象,垃圾对象,但是它还在占着内存,毕竟我们的电脑内存有限,所以应该有一个机制来回收它以及类似的对象.现在的高级语言如java,c#等,都采用了垃圾收集机制,而不再是c,c++里用户自己管理维护内存的方式.自己管理内存极其自由,可以任意申请内存,但如同一把双刃剑,为大量内存泄露,悬空指针等bug埋下隐患. 对于一个字符串.列表.类甚至数值都是对象,且定位简单易用的语言,自然不会

Python中的垃圾回收机制 | Python

-- python垃圾回收机制 # Python的GC模块(GarbageCollection)-- 垃圾回收模块 # 主要运用了引用计数来跟踪回收垃圾: 1.引用计数: # 对象被创建或者复制,引用计数加1:--> __init__ # 对象引用被销毁,引用计数减1: --> __del__ # 对象就没有再被使用,释放其内存: 1.优点:实时性,任何内存一旦没有引用指向就会立刻被回收: 2.缺点:a.维护引用计数的额外操作,跟运行中内存分配,释放,引用赋值成正比,效率低: b.造成循环引用

Python 中的垃圾回收机制

GC作为现代编程语言的自动内存管理机制,专注于两件事:1. 找到内存中无用的垃圾资源 2. 清除这些垃圾并把内存让出来给其他对象使用.GC彻底把程序员从资源管理的重担中解放出来,让他们有更多的时间放在业务逻辑上.但这并不意味着码农就可以不去了解GC,毕竟多了解GC知识还是有利于我们写出更健壮的代码. 引用计数 Python语言默认采用的垃圾收集机制是『引用计数法 Reference Counting』,该算法最早George E. Collins在1960的时候首次提出,50年后的今天,该算法依

编程语言类别;运行Python程序的方式;变量和常量;Python程序的垃圾回收机制;

---恢复内容开始--- 一.编程语言分类: 1.机器语言:直接用二进制的0和1和计算机(CPU)直接沟通交流,直接操作硬件. 优点:不需转换,计算机能直接读懂,执行速度快. 缺点:二进制代码复杂多样,理解甚难,开发效率低. ps:站在奴隶的角度说奴隶能够听得懂的话 0000 代表  加载 (LOAD) 0001代表 存储(STORE) 暂存器部分事例 0000  代表暂存器 A 0001  代表暂存器  B 存储器部分事例 000000000000  代表地址为 0的存储器 000000000

python中的垃圾回收

python中垃圾回收 以引用计数为主,但解决不了循环引用,以隔代回收为辅 import gc class A(): def __init__(self): print('object born, id:%s' % str(hex(id(self)))) def f2(): while True: a1 = A() a2 = A() a1.t = a2 a2.t = a1 del a1 del a2 gc.disable() f2() 这和链表有些类似: 原文地址:https://www.cnb

(编程语言+python+变量名+垃圾回收机制)*知识点

编程语言 从低级到高级的发展的过程 1.机器语言 计算机是基于电工作的.(基于高.低电平 1010010101011) 如果用机器语言表现一个字符的意思需要多段代码的行.但是计算机读取的快. 所以机器语言的 优点:执行速度够快 缺点:开发效率非常低 2.汇编语言 汇编语言的属性,汇编语言通过英文字符组成 优点:执行效率相较于机器语言略低 缺点:开发效率相较于机器语言略高 举个例子: ; hello.asm section .data ; 数据段声明 msg db "Hello, world!&q

python入门之垃圾回收机制、用户交互、算术运算符

1.垃圾回收机制详解 引用计数 引用计数:记录指向对象引用的个数 x=10l=['a','b',x] # l=['a'的内存地址,'b'的内存地址,10的内存地址] 引用分为直接引用和间接引用 直接引用:变量值的内存地址直接指向变量名 x = 10 间接引用:变量值的内存地址直接指向变量名,变量名作为一个元素,存储在容器中(list/dict) x = 11y = [5,x] 标记清除:用来解决循环引用带来的内存泄露问题 标记清除就是用来清除循环引用情况下引用计数无法清除的垃圾,python解释

Python引用复制,参数传递,弱引用与垃圾回收

引用 先上个示例: >>> val = [1] >>> val[0] = val >>> val [[...]] 上述代码使val中包含自身,而产生了无限递归.上述示例表明Python中的变量名为引用类型,赋值只是使得左值指向与右值相同的内存对象. is运算符可以判断两个引用是否指向了同一个对象,而==运算符判断两个引用指向的值是否相等而不关心指向什么对象. 对引用不了解的朋友,可以把Python引用与C/C++中的void *类比,不过因为垃圾回收机

python 垃圾回收

一.垃圾回收机制Python中的垃圾回收是以引用计数为主,分代收集为辅.引用计数的缺陷是循环引用的问题.在Python中,如果一个对象的引用数为0,Python虚拟机就会回收这个对象的内存. #encoding=utf-8 __author__ = '[email protected]' class ClassA(): def __init__(self): print 'object born,id:%s'%str(hex(id(self))) def __del__(self): print