美文网首页
python 内存分配和垃圾回收

python 内存分配和垃圾回收

作者: 四阿哥萌萌哒 | 来源:发表于2019-07-17 22:20 被阅读0次

内存分配

Python中的内存管理机制的层次结构提供了4层

最底层则是C运行的malloc和free接口

第一层则是在第0层的基础之上对其提供的接口进行了统一的封装,这是因为虽然不同的操作系统都提供标准定义的内存管理接口,但是对于某些特殊的情况不同的操作系统都不同的行为,比如说调用malloc(0),有的操作系统会返回NULL,表示内存申请失败;然而有的操作系统会返回一个貌似正常的指针,但是这个指针所指的内存并不是有效的。为了广泛的移植性,Python必须保证相同的语义一定代表相同的运行行为。

在第二层内存管理机制上,Python构建了更高抽象的内存管理策略,比如说一些常用对象,包括整数对象、字符串对象等等。

第三层主要是对象缓冲池机制,它基于在第二层的内存池。

内存池

Python为了避免频繁的申请和删除内存所造成系统切换于用户态和核心态的开销,从而引入了内存池机制,专门用来管理小内存的申请和释放。整个小块内存的内存池可以视为一个层次结构,其一共分为4层,从下之上分别是block、pool、arena和内存池。需要说明的是:block、pool和area都是代码中可以找到的实体,而最顶层的内存池只是一个概念上的东西,表示Python对于整个小块内存分配和释放行为的内存管理机制。

内存大小以256字节为界限,大于则通过malloc进行分配,小于则通过内存池分配。

内存池

block:最小的内存单元,大小为8的整数倍。有很多种类的block,不同种类的block都有不同的内存大小,申请内存的时候只需要找到适合自身大小的block即可,当然申请的内存也是存在一个上限,如果超过这个上限,则退化到使用最底层的malloc进行申请。

pool:一个pool管理着一堆有固定大小的内存块,其大小通常为一个系统内存页的大小。

arena:多个pool组合成一个arena。

GC

引用计数

python里每一个东西都是对象,它们的核心就是一个结构体:

typedef struct_object { 

     int ob_refcnt; 

     struct_typeobject *ob_type;

} PyObject;

PyObject,是每个对象必有的内容,其中ob_refcnt就是做为引用计数,引用计数为0时,该对象生命就结束了。

导致引用计数+1的情况

对象被创建,例如a=23

对象被引用,例如b=a

对象被作为参数,传入到一个函数中,例如func(a)

对象作为一个元素,存储在容器中,例如list1=[a,a]

导致引用计数-1的情况

对象的别名被显式销毁,例如del a

对象的别名被赋予新的对象,例如a=24

一个对象离开它的作用域,例如f函数执行完毕时,func函数中的局部变量(全局变量不会)

对象所在的容器被销毁,或从容器中删除对象

优点:

实时性:一旦没有引用,内存就直接释放了。不用像其他机制等到特定时机。实时性还带来一个好处:处理回收内存的时间分摊到了平时。

缺点:

维护引用计数消耗资源

循环引用

标记清除

标记-清除只关注那些可能会产生循环引用的对象,显然,像是PyIntObject、PyStringObject这些不可变对象是不可能产生循环引用的,因为它们内部不可能持有其它对象的引用。Python中的循环引用总是发生在container对象之间,也就是能够在内部持有其它对象的对象,比如list、dict、class等等

原理:1. 寻找跟对象(root object)的集合作为垃圾检测动作的起点,跟对象也就是一些全局引用和函数栈中的引用,这些引用所指向的对象是不可被删除的;2. 从root object集合出发,沿着root object集合中的每一个引用,如果能够到达某个对象,则说明这个对象是可达的,那么就不会被删除,这个过程就是垃圾检测阶段;3. 当检测阶段结束以后,所有的对象就分成可达和不可达两部分,所有的可达对象都进行保留,其它的不可达对象所占用的内存将会被回收,这就是垃圾回收阶段。(底层采用的是链表将这些集合的对象连接在一起)

分代回收

将系统中的所有内存块根据其存活时间划分为不同的集合,每一个集合就成为一个“代”,Python默认定义了三代对象集合,垃圾收集的频率随着“代”的存活时间的增大而减小。也就是说,活得越长的对象,就越不可能是垃圾,就应该减少对它的垃圾收集频率。那么如何来衡量这个存活时间:通常是利用几次垃圾收集动作来衡量,如果一个对象经过的垃圾收集次数越多,可以得出:该对象存活时间就越长。

import gc模块,并且is_enable()=True才会启动自动垃圾回收。

相关文章

  • python 内存

    Python内存管理 [TOC] 垃圾回收 动态语言: 对象和类型和内存都是运行是确定(内存地址分配是在运行是自动...

  • 01垃圾回收机制

    垃圾回收(Garbage Collection,GC) 垃圾回收就是释放垃圾占用的空间 内存的动态分配和垃圾回收,...

  • python 内存分配和垃圾回收

    内存分配 Python中的内存管理机制的层次结构提供了4层 最底层则是C运行的malloc和free接口 第一层则...

  • 面向对象

    1. 垃圾回收机制 垃圾回收机制:内存对象的管理,包括对象空间的分配和释放。 对象空间的分配:使用new关键字创建...

  • 内存管理

    内存管理1、什么时候触发垃圾回收? 垃圾回收器周期性运行,如果分配的内存非常多,那么回收工作也会很艰巨,确定垃圾回...

  • Java垃圾回收(GC)机制

    为什么需要垃圾回收 如果不进行垃圾回收,内存迟早都会被消耗空,因为我们在不断的分配内存空间而不进行回收。除非内存无...

  • 9.垃圾收集

    垃圾收集 JavaScript 具有自动垃圾回收机制,内存分配和回收实现自动管理。 函数中局部变量的生命周期 执行...

  • python拾遗7 - 垃圾回收

    垃圾回收机制 相比 C++ 的手动回收内存,python 的垃圾回收机制可谓是省心省力,判断是否回收一块内存,主要...

  • python必知必会12

    Python 的内存机制 内存机制主要包括垃圾收集和内存管理两部分。Python 主要使用基于引用计数的垃圾回收机...

  • 《深入理解Java虚拟机》(二)--垃圾收集器与内存分配策略(4

    内存分配与回收策略 对象的内存分配规则不是固定的,是取决于你使用的是哪种垃圾回收器组合和虚拟机中的内存参数,如果启...

网友评论

      本文标题:python 内存分配和垃圾回收

      本文链接:https://www.haomeiwen.com/subject/cplhlctx.html