• Python的内存管理和垃圾回收


    内存管理

    与Python对象创建相关的结构体

    #define _PyObject_HEAD_EXTRA            
        struct _object *_ob_next;           
        struct _object *_ob_prev;
         
    #define PyObject_HEAD       PyObject ob_base;
     
    #define PyObject_VAR_HEAD      PyVarObject ob_base;
     
     
    typedef struct _object {
        _PyObject_HEAD_EXTRA // 用于构造双向链表
        Py_ssize_t ob_refcnt;  // 引用计数器
        struct _typeobject *ob_type;    // 数据类型
    } PyObject;
     
     
    typedef struct {
        PyObject ob_base;   // PyObject对象
        Py_ssize_t ob_size; /* Number of items in variable part,即:元素个数 */
    } PyVarObject;

    对Python内存管理理解

    Python是由C语言开发。
    Python中所有对象的创建均与C语言中的两个结构体有关,分别是Pyobject和PyVarobject。
    在Python中创建由单个元素组成的对象时(比如float类型),会使用Pyproject结构体,在创建由多个元素组成的对象时,使用PyVarproject创建。
    Pyobject内部维护了数据类型,引用计数器,和双向链表,PyVarproject内部比Pyobject多了一个元素个数。
    在Python中,每创建一个对象,首先会开辟内存并对其进行初始化(引用计数器设为1),再将其对象添加到双向链表中(ref_chain)。
    再对对象进行重复引用时,该对象的引用计数器(ob_refcnt)会增加1,删除变量时(del 变量)会找到该变量对应的对象的引用计数器进行减1操作,
    如果计数器变为0,系统将会把该对象对应的内存作为垃圾(实际上会放到缓存链表free_list中,如果再次创建同类型(float和列表类型)数据时,不会重新开辟内存,就会把free_list中同类型的内存数据改变后,重新引用,减少了重新开辟内存的开销)。

    验证回收后的内存会先放在free_list中:

     会发现,删除float类型后,在创建float类型,不会重新开辟新内存。

    垃圾回收

    引用计数器为主,标记清除和分代回收为辅。

    1:引用计数器:为零时作为垃圾回收。
    2:标记清除:由于引用计数器无法解决循环引用的问题,多个元素组成的对象才可能造成循环引用。
       Python底层会将Python中所有对象分类成为两个链表,分别是由单个元素和多个元素组成的对象,Python内部会定期扫描由多个元素组成对象的链表,如果遇到循环引用,则让各自的计数器减1,如果此时计数器变为零则变成垃圾。
        
    3:分代回收:由于在标记清除扫描链表时,链表对象比较多,并且为了设置对象扫描的优先级,设置了分代回收,分别是0代,1代,2代。0代扫描十次,才会扫描1代一次,如果发现对象仍被引用,则进行升级,级别越高,成为垃圾的几率越小,扫描次数也越小,减少了系统扫描造成的资源消耗。
      注:对象链表长度为700,扫描一次。

    循环引用

    a=[1,2]
    b=[3,4]
    
    a.append(b) #a=[1,2,b]
    b.append(a) #b=[3,4,a]
    
    del a
    del b
    
    #del a b后,原a,b对应的引用计数器仍为1,因此会在内存中一直存在。
  • 相关阅读:
    初步掌握HBase
    基于HBase0.98.13搭建HBase HA分布式集群
    获取当前目录中的文件个数
    MapReduce链接作业
    MapReduce二次排序
    使用map端连接结合分布式缓存机制实现Join算法
    字符串匹配算法-BM
    统计电视机顶盒中无效用户数据,并以压缩格式输出有效用户数据
    字符串匹配算法-KMP
    MapReduce中的Join算法
  • 原文地址:https://www.cnblogs.com/sun-10387834/p/12824027.html
Copyright © 2020-2023  润新知