python内存管理总结

之前在学习与工作中或多或少都遇到关于python内存管理的问题,现在将其梳理一下。

python内存管理机制

  • 第0层 操作系统提供的内存管理接口 c实现
  • 第1层 基于第0层操作系统内存管理接口包装而成,目的是为python提供一层统一raw memory的接口
  • 第2层 第1层所提供的内存管理接口其功能是有限的 第二层内存管理接口 GC是在这层实现的
  • 第3层 在第2层内存管理机制上,对python的一些常用对象,构建了更高抽象层次的内存管理策略

小块空间的内存池

  • block 确定大小的内存块 源码中并无对应的实体存在 对象pyobject 列表pylistobject 管理block的对象pool 8字节
  • pool 对block进行管理 4kb
  • arena 对pool进行管理256kb 64个pool
  • 内存池 arena
  • pool三种used full empty
  • 若arena 中的empty pool个数为n 则从usable_arenas中开始寻找arena可以插入的位置,将arena插入到usable_arenas 这个操作的原因是由于usable_arenas实际上是一个有序的链表,从表头开始往后,每一个arena中的emptypool个数,即freepools,都不能大于后面的arena,也不能小于前面的arena。保持这种有序性的原因是分配block时,是从usable_arenas的表头开始寻找可用的arena的。如果一个arena的empty _pool数量越多,使用机会越少。最终释放其维护的pool集合的内存机会就越大

python内存管理及释放

  • 垃圾回收 对变量内存地址的分配是在运行时自动判断变量类型并对变量进行赋值
    • 当内存中有不再使用的部分时,垃圾收集器就会把他们清理掉。它会去检查那些引用计数为0的对象,然后清除其在内存的空间。当然除了引用计数为0的会被清除,还有一种情况也会被垃圾收集器清掉:当两个对象相互引用时,他们本身其他的引用已经为0了
    • 垃圾回收机制还有一个循环垃圾回收器, 确保释放循环引用对象(a引用b, b引用a, 导致其引用计数永远不为0)
  • 引用计数
  1. 引用计数增加
    • 对象被创建
    • 别名被创建
    • 作为参数传递给函数
    • 作为容器对象的一个元素
  1. 引用计数减少
    • 一个本地引用离开其作用域 函数结束
    • 对象别名被显式销毁 del x
    • 对象别名被赋值给其他对象 x = 789
    • 对象从一个窗口对象中移除 list.remove(x)
    • 窗口对象本身被销毁
  • 内存池机制

垃圾回收时,Python不能进行其它的任务。频繁的垃圾回收将大大降低Python的工作效率。如果内存中的对象不多,就没有必要总启动垃圾回收。所以,Python只会在特定条件下,自动启动垃圾回收。当Python运行时,会记录其中分配对象(object allocation)和取消分配对象(object deallocation)的次数。当两者的差值高于某个阈值时,垃圾回收才会启动。

分代回收策略:

Python将所有的对象分为0,1,2三代。所有的新建对象都是0代对象。当某一代对象经历过垃圾回收,依然存活,那么它就被归入下一代对象。垃圾回收启动时,一定会扫描所有的0代对象。如果0代经过一定次数垃圾回收,那么就启动对0代和1代的扫描清理。当1代也经历了一定次数的垃圾回收后,那么会启动对0,1,2,即对所有对象进行扫描。

 

posted @ 2021-03-30 18:04  简直😓  阅读(91)  评论(0编辑  收藏  举报