Python 内存管理机制

Python 内存管理机制

python 作为一门高级语言,自带内存管理机制,调用相关变量时,无需实现声明,变量无需指定类型,python 解释器会帮你自动回收,这一切都由python内存管理器承担了复杂的内存管理工作。

Python中的内存管理机制——Pymalloc

主要实现方式:

  1. 针对小对象,就是大小小于256kb时,pymalloc会在内存池中申请内存空间
  2. 针对大于256kb,会执行new/malloc行为来申请新的内存空间

python 内存池(memory pool)

特点:

  • 内存池的作用就是预先在内存中申请一定数量的,大小相等的内存块留作备用,当有新的内存需求时,就优先从内存池中分配给这个需求。

  • 减少内存碎片化,提升效率

    当创建大量消耗小内存的对象时,频繁调用new/malloc 会导致大量的内存碎片,导致效率降低。

工作机制:

结构图:

img

img

  • python 的对象管理主要位于 Level + 1 ~ Level +3 层

  • Level + 3 特定对象内存分配器:对于python内置的对象(int,dict)都有独立的私有内存池,对象之间的内存池不共享,即int释放的内存,不会被分配给float使用

  • Level + 2层 python 对象分配器:当申请的内存大小小于256KB时,内存分配主要由Python对象分配器(python’s object allocator)实施

  • Level + 1层 Python内存分配器 :当申请的内存大小大于256KB时,由Python 原生的内存分配器进行分配,本质上是调用C标准库中的malloc/readlloc等函数

关于释放内存方面,当一个对象的应用计数变为0时,Python 就会调用它的析构函数(__del__)。调用析构函数并不意味着最终一定会调用free来释放内存空间,会导致频繁地申请、释放内存空间会使得Python的执行效率大打折扣。因此在析构时也采用了内存池机制,从内存池申请到的内存会被归还到内存池中,以避免频繁地申请和释放动作。

垃圾回收机制

Python的垃圾回收机制采用引用计数机制为主标记-清除和分代回收机制为辅的策略。

  • 引用计数

    每个对象都会维护一个ob_ref——用来记录当前对象被引用的次数,也就是来追踪到底有多少应用指向了这个对象,

    对象的引用计数器+1

    1. 对象被创建 a = [1,23,4]
    2. 对象被引用 b = a
    3. 对象被作为参数,传到函数中 func(a)
    4. 对象作为一个元素,存储到容器中list = [1,a,2]

    对象的引用计数-1

    1. 对象的应用被显示销毁时,del a
    2. 对象的引用别名被赋予新的对象,a=26
    3. 一个对象离开它的作用域,例如func函数执行完毕时,函数里面的局部变量的引用计数器就会减一(全局变量不变)
    4. 将该元素从容器中删除时,或者容器被销毁

    当指向对象的内存的引用计数为0时,该内存会被Python虚拟机销毁

优点:1. 高效 2. 实时性,一旦没有引用,内存就直接释放了 3. 对象有确定的生命周期 4. 易于实现。

缺点:1. 维护引用计数消耗资源。2. 无法解决循环引用问题-

  • 标记清除

    针对循环引用的情况,这些对象的引用计数都是1而不是0 ,python的引用计数的算法不能够处理互相指向自己的对象。事实上,当你的python程序运行的时候它将建立一定数量的”浮点数垃圾“,Python 的GC不能够处理未使用的对象因为引用计数的值不会到零。

    关于python 引用Generational GC 算法

    [标记清除(Mark-Sweep)] 算法是一种基于追踪回收(tracing GC)技术实现的垃圾回收算法。主要针对一些容器对象,比如list、dict、tuple、instance等,对于字符串和数值对象是不可能造成循环引用的问题的。python对象都分为两部分: PyObject_HEAD + 对象本身数据

    其分为两个阶段:1. 第一阶段是标记阶段,GC会把所有的[活动对象]打上标记,第二阶段是把那些没有标记的对象[非活动对象]进行回收。

    活动对象和非活动对象的判定:

    对象之间通过引用(指针)连在一起,构成一个有向图,对象构成这个有向图的节点,而引用关系构成这个有向图的边。从根对象(root object)出发,沿着有向边遍历对象,可达的(reachable)对象标记为活动对象,不可达的对象就是要被清除的非活动对象。根对象就是全局变量、调用栈、寄存器。
    在这里插入图片描述

其中:1,2,3 为活动对象,4,5为非活动对象,会被回收

关于引用计数和标记清除的底层可以参考:https://blog.csdn.net/xiongchengluo1129/article/details/80462651

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值