-
概念
- 指的是一个对象从诞生到消亡的过程
- 当一个对象被创建时,会在内存中分配相应的内存空间进行存储
- 当这个对象不再使用,为了节省内存,就会将这个对象释放
-
涉及问题
- 如何监听一个对象的生命过程?
- python是如何掌控一个对象的生命?
-
监听对象生命周期
- __new__方法:
- 当我们创建一个对象时,用于给这个对象分配内存的方法
- 通过拦截这个方法,可以修改对象的创建过程,比如:单例设计模式
- __init__方法:
- __del__方法:
- __new__方法:
-
内存管理机制
-
存储方面
- 在python中万物皆对象:不存在基本数据类型
- 所有对象都会在内存中开辟一块内存进行存储
- 会根据不同的类型和内容,开辟不同空间大小进行存储
- 返回该空间的地址给外界接收(称为“引用”),用于后续对这个对象的操作
- 可通过id()函数获取内存地址(10进制)
- 可通过hex()函数查看对应的16进制地址
- 对于整数和短小的字符,python会进行缓存,不会创建多个相同的对象
- 容器对象存储的其他对象,仅仅是其他对象的引用,并不是其他对象本身
-
垃圾回收方面
-
引用计数器
-
概念
- 一个对象,会记录自身被引用的个数
- 每增加一个引用,这个对象的引用计数会自动+1
- 每减少一个引用,这个对象的引用计数会自动-1
-
举例
- 引用计数+1场景
- 对象被创建:p1 = Person()
- 对象被引用:p2 = p1
- 对象被作为参数,传入一个函数中
- 对象作为一个元素,存储在容器中:l = [p1]
- 引用计数-1场景
- 对象的别名被显示销毁:del p1
- 对象的别名被赋予新的对象:p1 = 123
- 一个对象离开它的作用域:一个函数执行完毕时;内部的局部变量关联的对象,它的引用无了
- 对象所在的容器被销毁,或从容器中删除对象
- 引用计数+1场景
-
查看引用计数
import sys sys.getrefcount(对象)#注意:会大一个,需要减一
-
-
垃圾回收
-
主要作用:从经历过“计数器机制”仍未被释放的对象中,找到“循环引用”,干掉相关对象
-
底层机制(了解&难)
-
怎样找到“循环引用”?
- 收集所有的“容器对象”,通过一个双向链表进行引用
- 容器对象:可以引用其他对象的对象(列表、元组、字典、自定义类对象等)
- 非容器对象:
- 针对每一个“容器对象”,通过一个变量gc_refs来记录当前对应的引用计数
- 对于每个“容器对象”,找到它引用的“容器对象”,并将这个“容器对象”的引用计数-1
- 经历过步骤3之后,如果一个“容器对象”的引用计数为0,就代表这玩意可以被回收了,肯定是“循环引用”导致它活到现在的
- 收集所有的“容器对象”,通过一个双向链表进行引用
-
如何提升查找“循环引用”的性能?
-
如果程序当中创建了很多个对象,而针对每一个对象都要参与“检测”过程,则会非常耗费性能
-
所以基于这个问题,产生了一种假设:命越大的对象,越长寿(假设一个对象10次检测都没给它干掉,那认定这个对象一定很长寿,就减少这货的“检测频率”)
-
基于这种假设,设计了一套机制:分代回收
-
机制:
- 默认一个对象被创建出来后,属于0代
- 如果经历过这一代“垃圾回收”后,依然存活,则划分到下一代
- “垃圾回收”的周期顺序为:0代“垃圾回收”一定次数,会触发0代和1代回收;1代“垃圾回收”一定次数,会触发0代,1代和2代回收
-
查看和设置相关参数:
import gc print(gc.get_threshold()) gc.set_threshold(700,10,5)
-
-
-
-
垃圾回收时机
- 自动回收:触发条件
- 开启垃圾回收机制
- gc.enable():开启垃圾回收机制(默认开启)
- gc.disable():关闭垃圾回收机制
- gc.isenabled():判定是否开启
- 并且达到了垃圾回收的阙值
- 垃圾回收器中,新增的对象个数和释放的对象个数之差达到某个阙值
- 涉及方法
- gc.get_threshold():获取自动回收阙值
- gc.get_threshold():设置自动回收阙值
- 开启垃圾回收机制
- 手动回收
- 自动回收:触发条件
-
-
特殊场景
-
-
测量对象的引用个数
-
python对象的生命周期、周期方法和内存管理机制
最新推荐文章于 2023-12-04 21:57:01 发布