对象的计数方法:
__new__ 运行在__init__之前,用来拦截对象的引用。
对象存储的原则:
python 万物皆对象,不存在基本数据类型
所有对象都会在内存中进行存储。存储地址id(),hex()查看16进制地址。
常用的数值,短小的字符,缓存,不会创建多个相同的对象。值相同的对象,id()值一样
容器对象存储的其他对象,仅仅是其他对象的引用,并不是其他对象本身。
python内存管理机制=引用计数器+垃圾回收机制
引用计数器(性能高)
增加引用一次,计数加一;减少引用一次,计数减一
查看引用计数 import sys sys.getrefcount(对象)
加一的场景(被创建/被引用/被作为参数传到函数中/作为一个元素存储在容器中)
减一的场景(被删除/被赋予新的对象/对象离开它的作用域/对象所在的容器被销毁)
垃圾回收机制(解决循环引用的问题)从经历过引用计数器机制仍未被释放的对象中,找到循环引用对象,干掉相关对象
--如何找到循环引用
1.收集所有的容器对象(可以引用其他对象的对象如列表/元组/字典/自定义类对象),通过一个双向链表进行引用
2. 对每个容器对象,通过一个变量gc_refs来记录当前的引用计数
3. 对每个容器对象,找到他引用的容器对象,并将容器对象的引用计数加1
4.经过以上步骤后,如果一个容器对象引用计数为0,代表可以回收
--循环引用 import objgraph objgraph.count() 查看对象个数
--提高循环引用的性能 :假设命越大活得越久,假设一对象10次检测没被干掉,认定此对象长寿,减少此对象的检测频率
机制:1.对象被创立后属于0代
2.如果经历过这一代垃圾回收后依然存活,则划分为下一代
3.垃圾回收的周期顺序;0代垃圾回收一定次数,会触发0代和1代回收
1代垃圾回收一定次数,会触发0代,1代和2代回收
查看和设置相关参数 import gc gc.get_threshold() gc.set_threshold(500,10,5)
垃圾回收器当中,新增的对象个数和消亡的个数达到一定阈值时,才会触发垃圾检测gc.set_threshold(500,10,5) 这里面的500 就是阈值, 10 为0代检测10次数触发1代检测,5为1代检测5次后触发0代/1代/2代检测
垃圾回收的时机(自动回收) gc.enable()/gc.isenabled)/gc.disable()
手动回收垃圾gc.collect()
weakref.ref()弱引用