Python 内存管理和垃圾回收简要记录

本文介绍了Python中的内存管理机制,包括内存池管理对小块内存的申请与释放过程。详细解析了Python垃圾回收机制的三个方面:引用计数、标记清除及分代收集,旨在帮助读者理解Python内存管理的核心原理。

内存管理

    Python引入了内存池机制, 用于管理对小块内存的申请和释放。

    如果需要分配的空间大于SMALL_REQUEST_THRESHOLD bytes(定义在Objects/obmalloc.c中,我的2.7.11版本是512),则直接使用系统的内存分配接口申请内存空间,主要是C中的malloc;否则从内存池中申请内存空间,涉及到的有block,pool和arena。在内存释放的时候,当对象的应用计数为0时,自动调用其析构函数,从内存池中申请来的内存会被归还到内存池中。

垃圾回收

    Python 中垃圾回收机制: 引用计数(主要), 标记清除, 分代收集(辅助)

引用计数

    当一个对象的引用被创建或者复制时,对象的引用计数加1;当一个对象的引用被销毁时,对象的引用计数减1;当对象的引用计数减少为0时,就意味着对象已经没有被任何人使用了,可以将其所占用的内存释放了。

    引用计数的优点在于“实时性”,缺点在于维护引用计数时所带来的效率问题和循环引用问题。

标记清除

    主要是为了解决循环引用问题。首先观察到循环引用只能被容器对象创造。容器对象是可以包含其他对象的引用的对象,例如列表,字典,实例,类和元祖,而整数和字符串不是容器对象。

    标记清除的方法使用双向链表来记录所有的容器对象,在容器对象中添加两个指针,以方便容器对象的快速插入和删除,且不需要额外的内存空间分配。同时,需要在容器对象中新增字段gc_refs,通过以下步骤找到循环引用:

  1. 对于每个容器对象,设置gc_refs的值为对象的引用计数。
  2. 对于每个容器对象,找到它引用的其它容器对象,并将它们的gc_refs值减1。
  3. 所有gc_refs大于1的容器对象是被容器对象集合外的对象所引用的。这些对象不能释放,所以把这些对象放到另外一个集合内。
  4. 被移走的对象所引用的对象也是不能被释放的,所以将他们和他们能访问到的对象都从目前的集合中移走。
  5. 目前集合中剩下的对象是仅被该集合中对象引用的,他们无法被python取到,也就是来及,现在可以去释放这些对象。

分代收集

    分代收集用来提升垃圾回收的效率。这一策略的基本假设是:存活时间越久的对象,越不可能是垃圾。

    Python将所有对象分为0,1,2三代。所有新建对象都是0代对象。当某一代对象经历过垃圾回收后依然存活,那么它就被归入下一代对象。垃圾回收启动时,一定会扫描0代对象,如果0代经过一定次数垃圾回收,那么就启动对0代和1代的扫描清理。当1代也经历了一定次数的垃圾回收后,那么会启动对0,1,2,即对所有对象进行扫描。通过gc.get_threshold()方法可以看到当前的默认分代收集配置,通过gc.set_threshold(700, 10, 5)来对这一配置进行调整。

   


转载于:https://my.oschina.net/adlibii/blog/668871

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值