• 弱引用的用途:在底层C++对象被上层python脚本对象使用时(转)


    在使用python脚本和底层C++对象进行交互的过程中发生了一个问题:由于底层C++对象的创建和删除决定权由底层决定,当底层决定删除这些对象而上层仍然在“强引用”这些对象的时候,就会导致“如果上层这些“强引用”不删除,则底层C++对象将一直留在内存里”的现象。
        什么情况下会出现这种情况呢?比如:场景管理器所管理的模型对象,当玩家很久没看到他们的时候,底层对象管理员会决定将这些对象删除掉以释放内存。但是,由于这些对象已经被上层python脚本所“强引用”,这个时候,就会出现这种浪费内存的现象了。
        如何解决这个问题呢?python提供了弱引用技术,请看下看。
     
    和许多其它的高级语言一样,Python使用了垃圾回收器来自动销毁那些不再使用的对象。每个对象都有一个引用计数,当这个引用计数为0时Python能够安全地销毁这个对象。

    使用weakref模块,你可以创建到对象的弱引用,Python在对象的引用计数为0或只存在对象的弱引用时将回收这个对象。

    创建弱引用

       你可以通过调用weakref模块的ref(obj[,callback])来创建一个弱引用,obj是你想弱引用的对象,callback是一个可选的函数,当因没有引用导致Python要销毁这个对象时调用。回调函数callback要求单个参数(弱引用的对象)。
     
        弱引用是对一个对象(称为 referent)的引用的持有者。使用弱引用后,可以维持对 referent 的引用,而不会阻止它被垃圾收集。当垃圾收集器跟踪堆的时候,如果对一个对象的引用只有弱引用,那么这个 referent 就会成为垃圾收集的候选对象,就像没有任何剩余的引用一样,而且所有剩余的弱引用都被清除。(只有弱引用的对象称为弱可及(weakly reachable)。)


    一旦你有了一个对象的弱引用,你就能通过调用弱引用来获取被弱引用的对象。下面的例子创建了一个对socket对象的弱引用:
    >>> from socket import *
    >>> import weakref
    >>> s=socket(AF_INET,SOCK_STREAM)
    >>> ref=weakref.ref(s)
    >>> s
    <socket._socketobject instance at 007B4A94>
    >>> ref
    <weakref at 0x81195c; to 'instance' at 0x7b4a94> 
    >>> ref()    #调用它来访问被引用的对象
    <socket.socketobject instance at 007B4A94>


    一旦没有了对这个对象的其它的引用,调用弱引用将返回None,因为Python已经销毁了这个对象。
    注意:大部分的对象不能通过弱引用来访问。

    weakref模块中的getweakrefcount(obj)和getweakrefs(obj)分别返回弱引用数和关于所给对象的引用列表。

    弱引用对于创建对象(这些对象很费资源)的缓存是有用的。

    创建代理对象

    代理对象是弱引用对象,它们的行为就像它们所引用的对象,这就便于你不必首先调用弱引用来访问背后的对象。通过weakref模块的proxy(obj[,callback])函数来创建代理对象。使用代理对象就如同使用对象本身一样:
    >>> from socket import*
    >>> import weakref
    >>> s=socket(AF_INET,SOCK_STREAM)
    >>> ref=weakref.proxy(s)
    >>> s
    <socket._socketobject instance at 007E4874>
    >>> ref 
    <socket._socketobject instance at 007E4874>
    >>> ref.close() #对象的方法同样工作


    callback参数的目的和ref函数相同。在Python删除了一个引用的对象之后,使用代理将会导致一个weakref.ReferenceError错误:
    >>> def s
    >>> ref
    Traceback (most recent call last):
      File "<stdin>", line 1, in ?
        上面对python提供的垃圾回收器和弱引用技术的
  • 相关阅读:
    Controller之daemonset
    Ubuntu下Zmap的安装
    VSCode无法加载PlatformIO按钮可能的原因(踩坑笔记)
    由于更换域名或者IP变更导致WordPressg无法进入后台的问题解决办法
    使用VSCode进行Arduino与ESP32开发配置指南
    Win7下阿米洛机械键盘蓝牙配置
    IIC通讯协议与SPI通讯协议小结
    如何在树莓派上搭建个人博客系统(踩坑笔记)
    STorM32 BGC三轴云台控制板电机驱动电路设计(驱动芯片DRV8313)
    #数据结构#什么是栈及栈的作用
  • 原文地址:https://www.cnblogs.com/bjdxy/p/2862709.html
Copyright © 2020-2023  润新知