整数在程序中的使用很是普遍,Python为了优化速度,使用了小整数对象池, 避免为整数频繁申请和销毁内存空间。java
Python 对小整数的定义是 [-5, 257) 这些整数对象是提早创建好的,不会被垃圾回收。在一个 Python 的程序中,全部位于这个范围内的整数使用的都是同一个对象.python
同理,单个字母也是这样的。app
可是当定义2个相同的字符串时,引用计数为0,触发垃圾回收函数
每个大整数,均建立一个新的对象。优化
python靠引用计数去维护什么时候释放内存spa
python里也同java同样采用了垃圾收集机制,不过不同的是: python采用的是引用计数机制为主,标记-清除和分代收集两种机制为辅的策略操作系统
引用计数机制:debug
python里每个东西都是对象,它们的核心就是一个结构体:PyObject
日志
typedef struct_object { int ob_refcnt; struct_typeobject *ob_type; } PyObject;
PyObject是每一个对象必有的内容,其中ob_refcnt就是作为引用计数。当一个对象有新的引用时,它的ob_refcnt就会增长,当引用它的对象被删除,它的ob_refcnt就会减小;当引用计数为0时,该对象生命就结束了。 code
list1 = [] list2 = [] list1.append(list2) list2.append(list1)
ist1与list2相互引用,若是不存在其余对象对它们的引用,list1与list2的引用计数也仍然为1,所占用的内存永远没法被回收,这将是致命的。 对于现在的强大硬件,缺点1尚可接受,可是循环引用致使内存泄露,注定python还将引入新的回收机制。(标记清除和分代收集)
GC系统所承担的工做远比"垃圾回收"多得多。实际上,它们负责三个重要任务。它们
为新生成的对象分配内存
识别那些垃圾对象,而且
从垃圾对象那回收内存。
当建立对象时,python当即向操做系统请求内存
中止程序,加标记,把未被标记的对象看成垃圾处理
对象被建立,例如a=23
对象被引用,例如b=a
对象被做为参数,传入到一个函数中,例如func(a)
对象做为一个元素,存储在容器中,例如list1=[a,a]
对象的别名被显式销毁,例如del a
对象的别名被赋予新的对象,例如a=24
一个对象离开它的做用域,例如f函数执行完毕时,func函数中的局部变量(全局变量不会)
对象所在的容器被销毁,或从容器中删除对象
import sys y='hh' print(sys.getrefcount(y))
import gc class ClassA(): def __init__(self): print('object born,id:%s'%str(hex(id(self)))) def f2(): while True: c1 = ClassA() c2 = ClassA() c1.t = c2 c2.t = c1 del c1 del c2 #把python的gc关闭 gc.disable() f2()
执行f2(),进程占用的内存会不断增大。
c1.t=c2
和c2.t=c1
后,这两块内存的引用计数变成2.1).import gc
gc.get_threshold()
输出:(700,10,10) (当没有释放的对象个数超过700,即开始0级垃圾回收,0级垃圾回收超过10次即开始1级垃圾回收,1级垃圾回收清除包括0级垃圾,1级垃圾回收超过10次,即开始2级垃圾回收,2级垃圾回收清除包括0级,1级垃圾)
2).垃圾回收机制python默认开启的,gc.disabled可关闭垃圾回收机制,当程序完成时,垃圾最后仍被回收
3).当gc.disabled时,gc.collect手动开启垃圾回收机制
gc模块提供一个接口给开发者设置垃圾回收的选项
。上面说到,采用引用计数的方法管理内存的一个缺陷是循环引用,而gc模块的一个主要功能就是解决循环引用的问题。
一、gc.set_debug(flags) 设置gc的debug日志,通常设置为gc.DEBUG_LEAK
二、gc.collect([generation]) 显式进行垃圾回收,能够输入参数,0表明只检查第一代的对象,1表明检查一,二代的对象,2表明检查一,二,三代的对象,若是不传参数,执行一个full collection,也就是等于传2。 返回不可达(unreachable objects)对象的数目
三、gc.get_threshold() 获取的gc模块中自动执行垃圾回收的频率。
四、gc.set_threshold(threshold0[, threshold1[, threshold2]) 设置自动执行垃圾回收的频率。
五、gc.get_count() 获取当前自动执行垃圾回收的计数器,返回一个长度为3的列表