语句x=3我们将3赋值给x。x是第一个引用,因此,该对象的引用计数被设置为1。语句y=x创建了一个指向同一对象的别名y。事实上并没有为y创建一个新的对象,而是该对象的引用计数增加了一次(变成了2)。这是对象引用计数增加的方式之一。还有一些其他的方式也能增加对象的引用计数,比如该对象作为参数被函数调用或这个对象被加入到某个列表等对象当中。
总之,对象的引用计数增加是:
对象被创建
x = 3
另外的别名被创建
y = x
作为参数传递给函数
foo(x)
成为容器对象的一部分
mylist = [1,2,x,‘xyz’]
3.3 减少引用计数
当对象的引用被销毁时,引用计数会减小。最明显的例子就是当引用离开其作用范围时,这种情况最经常出现在函数运行结束时,所有的局部变量都被自动销毁,对象的引用计数也就随之减少。
当变量被赋值给另外一个对象时,原对象的引用计数也会自动减1:
当字符串对象“xyz”被创建并赋值给foo时,它的引用计数是1。当增加一个别名bar时,引用计数变成了2。不过当foo被重新赋值给整型对象123时,xyz对象的引用计数自动减1,又重新变成了1。
其他造成对象引用计数减少的方式包括使用del语句删除一个变量,或者当一个对象被移出一个窗口对象时。
对象引用计数减少的情况:
一个本地引用离开了其作用的范围。比如foo() 函数结束时。
对象别名被显式销毁
del y
对象的一个别名被赋值给其他对象
x = 123
对象被从一个窗口对象中移除
mylist.remove(x)
窗口对象本身被销毁
del mylist
四、垃圾收集
不再使用的内存会被一种称为垃圾收集的机制释放。像上面说的,虽然解释器跟踪对象的引用计数,但垃圾收集器负责释放内存。垃圾收集器是一块独立代码,它用来寻找计数为0的对象。它也负责检查那些虽然引用计数大于0但也应该被销毁的对象。特定情形会导致循环引用。