内存管理机制 & 垃圾回收机制

内存管理机制

python是由c开发出来的。
看源码分析,下载python安装包tar包
解压后主要看Include和Objects这两个文件夹

# 分析
在创建对象时,如 v = 0.3
源码内部:
      a. 开辟内存
      b. 初始化
            ob_fval=0.3
            ob_type=float #类型
            ob_refcnt=1   #计数器
      c.将对象加入到双向联表中 ref_chain
操作:
      name = v  # 将name也指向v的内存地址,不会重新开辟空间
源码内部:
      ob_refcnt+1  #计数器加1

操作:
      del v
源码内部:
      ob_refcnt-1  #计数器-1

操作:
      def fun(arg):
            print(123)
      fun(name)
源码内部:
      刚进去的时候ob_refcnt+1 # 计数器+1
      运行结束的时候ob_refcnt-1 #计数器-1

操作:
      del name
源码内部:
      ob_refcnt-1  #计数器-1
      每次应用计数器减一时,都会检查是否以为0,如果是0,则认为它是垃圾,就回对它进行回收

# 缓存机制
python内部为了提升效率,会做一些缓存机制
比如:
v = 0.3
name = v
del v
id(name)  # 66217
del name
xx = 66.66
id(xx)  # 66217
按理说当name和v都被删除后,应该会销毁,但是并没有,这里主要是因为缓存的机制
所以xx的内存地址会跟name的内存地址一致。

# 总结
# 内存管理机制
python是由c语言开发,操作都是基于底层c语言实现,python中创建每个对象,内部都会与c语言结构体维护一些值,PyObject(双向链表,引用计数器,类型)和PyVarObject(PyObject,容量个数),在创建对象时,每个对象至少内部有4个值(双向链表,引用计数器,类型),创建对象之后会对内存中的数据进行初始化,初始化本质:引用计数器=1,赋值,然后将对象添加到双向链表中refchain.以后再有其它变量指向这个内存,则让引用计数器+1,如果销毁某个变量,则找到它指向的内存,将其引用计数器-1.引用计数器如果为0,则进行垃圾回收。
在内部可能存在缓存机制,例如:float(100)/int(257)/list(80), 最开始时不会真正销毁,而是放在free_list的链表中,以后再创建同类型的的数据时,会先去链表中取出对象,然后再对对象初始化。

# 垃圾回收机制
引用计数器为主,标记清除和分代回收为辅。
引用计数器会出现循环引用(容器类会出现)
标记清除:针对那些容器类的对象,在python中会将他们单独放到一个双项链表中,做定期扫描,检查是否有循环引用,如果有则各自-1,如果-1之后等于0,则直接回收。
分代回收:为了少扫描对象,将没有问题的对象让它放到上一级的链表中,默认下一级扫10次,上一代才扫描1次,总共有3代。
posted @ 2020-11-29 20:38  我在路上回头看  阅读(10)  评论(0编辑  收藏  举报