首页 > 编程语言 >Python之垃圾回收机制

Python之垃圾回收机制

时间:2022-11-29 20:03:05浏览次数:38  
标签:Python 回收 python 计数 对象 l2 垃圾 l1

什么是垃圾回收

    当为一个变量分配数据的时候,python会在内存中分配一部分空间,用户储存此数据,但内存空间总是有限的,如果一直占用内存空间,内存迟早会溢出,所以,程序中需要把无用的数据从内存中删除,回收内存空间,这个过程就叫作垃圾回收。
    python采用的是引用计数机制为主,标记-->清除和分代收集(隔代回收)两种机制为辅的策略。

垃圾回收中的计数

    python里每一个东西都是对象,它们的核心就是一个结构体:PyObject
    PyObject是每个对象必有的内容,其中ob_refcnt就是做为引用计数。当一个对象有新的引用时,它的ob_refcnt就会增加,当引用它的对象被删除,它的ob_refcnt就会减少
    简单来说,当一个变量被赋值一次时,这个变量此时的计数为1,当这个变量被其它变量引用时,此时的计数将会加1,当引用它的对象被删除时,它的计数将会减少1,当计数为0时,此时的这个变量对应的数据则为垃圾数据,此数据就会被回收。

import sys
name = 'a'
print(sys.getrefcount(name))  # 返回值11,初始值为什么是11而不是1?后续需要查答案
name1 = name
print(sys.getrefcount(name))  # 返回值12,多引用了一次,计数器加1
name2 = name1
print(sys.getrefcount(name))  # 返回值13,再次引用,计数器加1
del name1
print(sys.getrefcount(name))  # 返回值12,删除一个变量,计数器减1

垃圾回收中的 标记->回收

计数问题产生了一个新的问题,就是循环引用无法回收,什么是循环引用,代码如下:

l1 = [1, 2]  # 此时l1的计数假设为1
l2 = [3, 4]  # 此时l2的计数假设为1
l1.append = l2  # 此时l2的计数为2
l2.append = l1  # 此时l1的计数为2
del l1  # 此时l1的计数为1
del l2  # 此时l2的计数为1

上面的代码可以明白,由于互相引用的情况下产生了循环引用,此时删除了l1与l2两个变量是无法让计数变为0的,那么内存就无法得到释放,为了解决这个问题,python出现了一个 标记 -> 回收机制。
当内存不够用时,python会去检查代码中的所有内存中的数据值,如果发现了一个循环引用的值时,就会打上标记,当python检查完内存中所有数据值时,将会一次性回收所有的被打过标记的数据值。

Python中的分代回收

分代回收是一种以空间换时间的机制。

  1. python会将内存对象根据存活时间划分为三个不同的集合。每个集合可以称为一个代。可以理解为“第0代”,“第1代”,“第2代”,他们对应的是3个链表,它们的垃圾收集频率随着对象存活时间的增大而减小。
  2. 新创建的对象都被分配到“第0代”中,当“第0代”的链表总数量达到上限时,python的垃圾回收机制将被触发,将回收可回收对象,并将不可回收对象放到“第1代”链表中,依次类推,“第2代”链表中的对象为存活时间最久的对象,甚至存活整个系统的生命周期内。
  3. 分代回收是建立在标记清除技术基础之上。分代回收同样作为Python的辅助垃圾收集技术处理那些容器对象。

而分代回收被创建的原因就是为了节省系统运行的资源,系统可能会频繁的去检查“第0代”链表中的对象,而对于“第1代”链表中的对象则相对来说不会太过频繁去检查,而“第2代”链表中的对象可能很长时间才会检查一次,以此来节省运算资源。

标签:Python,回收,python,计数,对象,l2,垃圾,l1
From: https://www.cnblogs.com/smyz/p/16936519.html

相关文章

  • Python之八大数据类型
    数据类型之整型int与浮点型float整型也就是int型其实就是整数如:print(type(10))浮点型就是float其实就是小数如:print(type(10.0))#这里需要注意:10.0也......
  • Python常见部分内置方法与操作
    Python常见内置方法与操作整型int类型转换int(其它数据类型),但只支持数字类型和小数类型>>>num1=input('Yourage>>>:')Yourage>>>:18>>>print(type(num1)......
  • python之路38 SQL注入问题 索引触发器 事务 存储过程 函数 流程控制
    SQL注入问题怪像1:输对用户名就可以登录成功怪像2:不需要对的用户名和密码也可以登录成功SQL注入:利用特殊符号的组合产生特殊的含义从而避开正常的业务逻辑select......
  • 从零开始学Python【37】--朴素贝叶斯模型(理论部分)
    【知识铺垫】在介绍如何使用贝叶斯概率公式计算后验概率之前,先回顾一下概率论与数理统计中的条件概率和全概率公式:如上等式为条件概率的计算公式,表示在已知事件A的情况下事......
  • build a python env on ubuntu20.04
    buildapythonenvonubuntu20.04fixvirtualenvwarpper(Ubuntu20.04安装virtualenv方法以及安装过程中遇到的问题处理)[https://blog.csdn.net/qq_42296146/article/d......
  • python请求nginx basic认证的页面
    python请求nginxbasic认证的页面问题:python在请求过程中会遇到nginx反向代理并通过basic设置了用户名密码校验的页面或者接口,此时直接requests请求回返回401,那么下面就......
  • Python后端开发(主Django)面试题
    最近两个后端同事离职了,帮忙面试了些后端开发的实习生,虽然有过一些后端经验,但我不是主要写后端的,复习了下Django也稍微准备了一些主要是Django相关的面试题,数据库相关部分额......
  • Python调用百度地图api获取起点终点距离和预估时长
    去百度地图开放平台申请API的AKhttps://lbsyun.baidu.com/apiconsole/center#/homeimportpandasaspdimportrequests,jsonAK="xxxx"#获取位置defgetPos......
  • python爬取m3u8视频文件
    importrequestsimportosimportaiohttpimportasynciofirst_m3u8_url="https://cdn.zoubuting.com/20221129/waHIjBSS/index.m3u8"headers={'User-Agent......
  • python性能调优之key-query
    近期接触到一个性能调优的问题,需要在mongodb中比对大约100G的csv文件的key在mongodb中是否存在baseline首先做一个什么优化都没有的情况下的基准测试:bat......