python_如何在循环引用中管理内存?

案例:

  python中通过引用计数来回收垃圾对象,在某些环形数据结构(树,图……),存在对象间的循环引用,比如树的父节点引用子节点,子节点同时引用父节点,此时通过del掉引用父子节点,两个对象不能被立即释放

需求:

如何解决此类的内存管理问题?

如何查询一个对象的引用计数?

import sys

sys.getrefcount(obj)

# 查询引用计数必多 1 ,因为object也引用 查询对象

如何解决内存管理问题?

  1. 通过weakref,进行弱引用,当del时候,不再引用,在引用方添加weakref.ref(引用obj),
  2. 使用引用的时候,需要用到函数调用的形式

    #!/usr/bin/python3
    
    import weakref
    import sys
    
    class Data(object):
        def __init__(self, value, owner):
            self.value = value
    
            # 声明弱引用,owner为Node类本身
            self.owner = weakref.ref(owner)
    
        # 通过函数调用的方式访问引用对象
        def __str__(self):
            return "%s‘s data, value is %s" % (self.owner(), self.value)
    
        def __del__(self):
            print(‘in_data.__del__‘)
    
    class Node(object):
        def __init__(self, value):
    
            # 把类本身,也当做参数传入Data类中
            self.data = Data(value, self)
    
        # 自定义对象名,容易辨认
        def __str__(self):
            return ‘Node‘
    
        def __del__(self):
            print(‘in_node.__del__‘)
    
    if __name__ == ‘__main__‘:
        node = Node(100)
        print(node.data)
    
        # 打印node对象的引用计数
        print(sys.getrefcount(node) - 1)
    
        # 当删除node对象时候,Data实例对象在引用计算为0也相应释放
        del node
    
        input(‘del done >>>>>‘)
    

      

时间: 2024-10-07 07:22:20

python_如何在循环引用中管理内存?的相关文章

检测项目中的循环引用引起的内存问题

说到检测项目中的循环引用 可以有很多手段,其中牛叉的 instruments 当然是把利器. 当然开发过程中往往会大意引起的 循环引用 比如:忘写了 @weakify(self) && @strongify(self); 在大量使用RAC 和 block..... 当然引起这类原因还有很多... 如果分工明确的话可能会再项目结束后,专门测试这块...然而好像并不是每次迭代都会做这块的工作,除非被明确发现引起崩溃的情况. so  要是能把这个工作引入debug 期间,如果引起循环引用 可以抛

Block 循环引用(中)

不会造成循环引用的block 大部分GCD方法 1 dispatch_async(dispatch_get_main_queue(), ^{ 2 [self doSomething]; 3 }); 因为self并没有对GCD的block进行持有,没有形成循环引用.目前我还没碰到使用GCD导致循环引用的场景,如果某种场景self对GCD的block进行了持有,则才有可能造成循环引用. block并不是属性值,而是临时变量 1 - (void)doSomething { 2 [self testWi

block使用小结、在arc中使用block、如何防止循环引用

引言 使用block已经有一段时间了,感觉自己了解的还行,但是几天前看到CocoaChina上一个关于block的小测试主题 : [小测试]你真的知道blocks在Objective-C中是怎么工作的吗?,发现竟然做错了几道, 才知道自己想当然的理解是错误的,所以抽时间学习了下,并且通过一些测试代码进行测试,产生这篇博客. Block简介(copy一段) Block作为C语言的扩展,并不是高新技术,和其他语言的闭包或lambda表达式是一回事.需要注意的是由于Objective-C在iOS中不支

iOS-旧项目中手动内存管理(MRC)转ARC

在ARC之前,iOS内存管理无论对资深级还是菜鸟级开发者来说都是一件很头疼的事.我参 加过几个使用手动内存管理的项目,印象最深刻的是一个地图类应用,由于应用本身就非常耗内存,当时为了解决内存泄露问题,每周都安排有人值班用 Instruments挨个跑功能,关键是每次都总能检查出来不少.其实不管是菜鸟级还是资深级开发者都避免不了写出内存泄露的代码,规则大家都懂,可是 天知道什么时候手一抖就少写了个release? 好在项目决定转成ARC了,下面将自己转换的过程和中间遇到的问题写出来和大家共享,希望

黑马程序员--Objective-C之--OC中的内存管理

对于面向对象的变成语言,程序需要不断地创建对象. 初始,创建的所有程序通常都有指针指向它,程序可能需要访问这些对象的实例变量或调用这些对象的方法,随着程序的不断执行,程序再次创建了一些新的对象, 而那些老的对象已经不会再被调用,也不再有指针指向他们,如果程序没有回收他们占用的内存,就会出现内存泄露. 如果程序一直泄露内存,那么可用内存就会越来越少,直到没有足够的内存,程序將会崩溃.目前,主要有两种管理内存的技术,一是引用计数,二是垃圾回收. iOS平台目前只支持引用计数,Mac平台支持垃圾回收.

使用gc、objgraph干掉python内存泄露与循环引用!

Python使用引用计数和垃圾回收来做内存管理,前面也写过一遍文章<Python内存优化>,介绍了在python中,如何profile内存使用情况,并做出相应的优化.本文介绍两个更致命的问题:内存泄露与循环引用.内存泄露是让所有程序员都闻风丧胆的问题,轻则导致程序运行速度减慢,重则导致程序崩溃:而循环引用是使用了引用计数的数据结构.编程语言都需要解决的问题.本文揭晓这两个问题在python语言中是如何存在的,然后试图利用gc模块和objgraph来解决这两个问题. 注意:本文的目标是Cpyth

JavaScript 中的内存泄漏

JavaScript 是一种垃圾收集式语言,这就是说,内存是根据对象的创建分配给该对象的,并会在没有对该对象的引用时由浏览器收回.JavaScript 的垃圾收集机制本身并没有问题,但浏览器在为 DOM 对象分配和恢复内存的方式上却有些出入. Internet Explorer 和 Mozilla Firefox 均使用引用计数来为 DOM 对象处理内存.在引用计数系统,每个所引用的对象都会保留一个计数,以获悉有多少对象正在引用它.如果计数为零,该对象就会被销毁,其占用的内存也会返回 给堆.虽然

c++智能指针以及循环引用问题(转)

解决循环引用: 在知道存在循环引用的条件下,使用boost::weak_ptr,即弱引用来代替循环引用中的某个强引用,从而打破循环引用的环. 由于 C++ 语言没有自动内存回收机制,程序员每次 new 出来的内存都要手动 delete,比如流程太复杂,最终导致没有 delete,异常导致程序过早退出,没有执行 delete 的情况并不罕见,并造成内存泄露.如此c++引入 智能指针 . c++ 智能指针主要包括:unique_ptr,shared_ptr, weak_ptr, 这三种,其中auto

循环引用,看我就对了

循环引用,看我就对了 我是一头来自北方的羊,咩-咩-咩-!谈到循环引用,不知道你能想到什么?可能是delegate为啥非得用weak修饰,可能是block为啥总是需要特殊对待,你也可能仅仅想到了一个weakSelf,因为它能帮你解决99%的关于循环引用的事情.本文中,我将谈一谈我对循环引用的看法. 一.循环引用的产生 1.基本知识 首先,得说下内存中和变量有关的分区:堆.栈.静态区.其中,栈和静态区是操作系统自己管理的,对程序员来说相对透明,所以,一般我们只需要关注堆的内存分配,而循环引用的产生