引用计数
在python中,每个对象都有存有该对象的引用总数,即引用计数(feference count)
引用计数原理
1.每个对象维护一个ob_ref减1,用来记录该对象当前被引用的次数
2.每当新的引用指向该对象时,它的引用计数ob_ref加1
3.每当该对象的引用失效时ob_ref减1
4.一旦对象的引用计数为0,该对象可以被回收,对象占用的内存空间将被释放
5.它的缺点是需要额外的空间维护计数,这个问题是其次的
6.最主要的问题是它不能解决对象的“循环引用”
获取引用计数.getrefcount()
from sys import getrefcount
a = [1,2,3]
print(getrefcount(a))
b = a
print(getrefcount(b))
#结果:
2
3
# 当使用某个引用计数作为参数,传递给getrefcount()时,
#参数实际上创建了一个临时的引用,
#因此,getrefcount()所得到的的结果,会比期望多1.
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
增加引用计数
当一个对象A被另一个对象B引用时,A的引用计数将加1
from sys import getrefcount
a = [1,2,3]
print(getrefcount(a))
b = [a,a]
print(getrefcount(a))
#结果:
2
4
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
减少引用计数
del删除或重新引用时,引用计数会变化(del只是删除引用)
from sys import getrefcount
a = [1,2,3]
b = a
print(getrefcount(b))
del a
print(getrefcount(b))
#结果:
3
2
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
循环引用的情况
x = []
y = []
x.append(y)
y,append(x)
对于上面相互引用的情况,如果不存在其他对象对他们的引用,
这两个对象所占用的内存也还是无法回收,从而到时内存泄露
>>> x = []
>>> y = []
>>> x.append(y)
>>> x = [1]
>>> y = [2]
>>> x.append(y)
>>> x
[1, [2]]
>>> y.append(x)
>>> y
[2, [1, [...]]]
>>>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14