首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Python语言特性:弱引用与强引用

每一门包含垃圾回收器的语言中,不可避免的存在引用的两个问题:强引用与弱引用。

当一个对象赋值时,默认就是强引用类型,即必须等待该对象所有的引用计数为,对象内存才会被回收。当出现循环引用或缓存对象时,如不进行显示清除,则可能会导致系统内存泄露(根据不同的垃圾回收算法决定)。弱引用则可以解决这些问题,当系统出现内存紧张时,不用显示析构对象,垃圾回收器会自动回收弱引用对象,弱引用被引用后,引用计数也不会增加;弱引用实际上在目标对象中增加了一层代理。

import weakref,sys

import os,time

class A:

def __init__(self,obj):

self.obj = obj

print("class A")

def __call__(self,obj=None):

print("Call A")

def __del__(self):

print("del A")

def func(self):

print("A func.")

class B:

def __init__(self):

self.obj = None

print("class B")

def __call__(self,obj=None):

print("call B")

def __del__(self):

print("del B")

def func(self):

print("B func")

if__name__ == "__main__":

o =B()

b = weakref.ref(o)

a = A(b)

print("ref counta:%s,b:%s,b():%s"%(sys.getrefcount(a),sys.getrefcount(b),sys.getrefcount(b())))

b().obj = a

print("ref counta:%s,b:%s,b():%s"%(sys.getrefcount(a),sys.getrefcount(b),sys.getrefcount(b())))

del a

print("sleep now.")

time.sleep(3)

上面的程序中,对象b为弱引用,A,B嵌套引用,循环引用现象并未导致内存泄露输出结果如下:

class B

class A

ref count a:2,b:3,b():2

ref count a:3,b:3,b():2

sleep now.

del B

del A

getrefcount函数实参引用了一个对象故比原引用多了一个引用,对象a、对象b创建初始计数为1,对象b被对象a引用、初始创建引用计数为2;当b的代理对象引用对象a后,a的引用计数则增加为2。

强引用之间的循环引用则会导致内存泄露。如下面的实例:

b = B()

a = A(b)

b.obj = a

del a

del b

输出结果如下:

class B

class A

对象a、b均未释放,产生了内存泄露。

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180414G16DLE00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券