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

python垃圾回收机制

时间:2024-03-19 15:29:56浏览次数:36  
标签:阈值 python 回收 对象 垃圾 threshold 引用

Python中的垃圾回收机制是自动的,它主要使用了引用计数来追踪和回收内存。

1、引用计数

当一个对象被创建时,就会被分配一块内存,然后将其引用计数设置为1。当另一个变量引用该对象时,引用计数就会增加1。当一个对象的引用计数变为0时,说明该对象没有任何引用,Python解释器就会将其回收并释放相应的内存。

下面给个例子去解释引用计数

1、误区例子

import sys


a = 1
print(f'对象a:{sys.getrefcount(a)-1}')
b = 10
print(f'对象a:{sys.getrefcount(a)-1},对象b:{sys.getrefcount(b)-1}')
# 输出结果:
# 对象a:96
# 对象a:96,对象b:14

如图,我这a,b在例子中只引用了一次,但输出结果可知a和b的引用计数不是一次;是因为python自带的由整数常量池 [-5, 256] ,在这个区间的整数,被称为小整数对象,所以自定义一个其他类型的数据。

那我用一个整数常量池之外的数据尝试一下

在 .py文件中,内存地址是一样的:
在这里插入图片描述
在终端执行,内存地址是不一样的:
在这里插入图片描述
由两图可知,解释器将 .py文件进行编译的时候,逐行进行解释,发现a和b的变量的内存地址一样,解释器会优化代码,则将两个变量指向同一块内存地址,以减少内存的开销。

2、正确例子

import sys

class X:
    pass

a = X()  # a引用次数加1

print(f'对象a:{sys.getrefcount(a)-1}')
c = a  # a引用次数加1, c引用次数为a的引用次数2
print(f'对象a:{sys.getrefcount(a)-1}, 对象c:{sys.getrefcount(c)-1}')

# 输出结果:
# 对象a:1
# 对象a:2, 对象c:2

引用次数加1条件:

对象被创建,例如a=1
对象被引用,例如b=a
对象被作为参数,传入到一个函数中,例如func(a)
对象作为一个元素,存储在容器中,例如 a_list=[a,a]

引用次数减1条件:

对象被显式销毁,如del a。
变量重新赋予新的对象,例如a=1。
对象离开它的作用域,如函数执行完毕时,函数中的局部变量(全局变量不会)。
对象所在的容器被销毁,或从容器中删除对象。

这样的缺点是:假如循环引用的话,其引用计数一直不为0,就不会被回收,就会浪费资源,就引进了下面两种方式进行回收。

2、标记&清除

标记:标记所有能够被程序访问到的对象(root objects),如全局变量、栈中的变量等,将它们标记为“活跃”对象;对于标记的对象,遍历它们的引用,将引用的对象标记为“活跃”对象;
清除:对于未被标记的所有对象,将它们标记为“垃圾”,即将它们回收清除。


class X:
    def aaa(self):
        return 1
def func():
    a3 = X().aaa()
    a2 = 3 + a3  # 为了表明a2是跟a3相关的
    a1 = a2 + a3  # 为了表明a1是跟a2,a3相关的

    c1 = a2
    c2 = c1 + a1

    b1 = X()
    b2 = X()

    b1.obj = b2
    b2.obj = b1

    return [a1, a2, a3]


A = func()

在这里插入图片描述

如图,A,a1,a2,a3,b1,b2,c1,c2都是被标记的对象;其中A,a1,a2,a3都被标记为“活跃”对象,b1,b2,c1,c被标记为“垃圾”;垃圾就进行回收,“活跃”对象就进行保存。
因为只有“活跃”对象到最后一步被使用,“垃圾”没有被使用

3、分代回收

1、将所有收集的对象放到一起;
2、遍历集合中的所有对象,将其分为两个引用计数为0和引用计数大于0的两个集合;
3、大于0的放到更老的一代,等于0的进行回收
4、或者是触发了GC中的阈值,进行回收

设置各世代的阈值:

import gc
threshold = gc.get_threshold()
print("各世代的阈值:", threshold)

# 设置各世代阈值
# gc.set_threshold(threshold0[, threshold1[, threshold2]])
gc.set_threshold(800, 20, 20)

threshold = gc.get_threshold()
print("各世代的阈值2:", threshold)

在执行分代回收的时候,程序会被暂停;就譬如说你嗑瓜子,是将瓜子扔在地上的,你妈妈正在扫地,假如你一直嗑瓜子,你妈妈就一直会扫不干净。为了减少程序暂停时间,就采用分代回收去收集清理垃圾,来减少耗时。

4、什么是阈值?

Python分代回收中的阈值是指两个用于判断对象是否应该被垃圾回收的阈值:第一个是每代的阈值,第二个是总体的阈值。

每代的阈值指的是每个分代的垃圾回收阶段执行的次数。每当达到每代的阈值时,Python会触发分代垃圾回收。

总体的阈值则是用于在分代回收期间控制是否触发全局垃圾回收(即回收所有代)的阈值。当某个分代的垃圾回收次数达到总体的阈值时,Python会触发全局垃圾回收。

这两个阈值都可以通过gc.get_threshold()函数获取,它返回一个三元组 (gen0, gen1, gen2),其中 gen0 为每代的阈值, gen1 为总体的阈值。

标签:阈值,python,回收,对象,垃圾,threshold,引用
From: https://blog.csdn.net/leshen_88/article/details/136797589

相关文章

  • python(pip)包/模块:如何离线安装?
    1、生成requirements.txt文件如果有同环境服务器,可直接生成requirements.txt,会把当前服务器下的包和版本写入文件中。pipfreeze>requirements.txt如安装指定包,创建requirements.txt,输入包名==版本号//只输入包名,默认最新版本。例:xlwt==1.3.02、下载包在requirements.t......
  • Python数据库模块(sqlite3,SQLite3)
    一、sqlite命令创建数据库:在控制台sqlite3name.databases查看数据库.tables查看表格名databaseName.dump>dumpName将数据库存在文本文件dumpName中,恢复就用databaseName<dumpName;attachdatabase......
  • Python中常用网络编程模块
    一、网络基础网络由下往上分为:物理层、数据链路层、网络怪、传输层、会话层、表示层和应用层。TCP/IP协议是传输层协议,主要解决数据如何在网络中传输;socket则是对TCP/IP协议的封装,它本身不是协议,而是一个调用接口;HTTP、FTP是应用协议,主要解决如何包装数据;TCP连接的三次握手:......
  • Python环境下基于注意力机制的小样本轴承故障诊断
    传统的基于特征提取与分类相结合的轴承智能诊断算法,对信号处理要求很高的专家经验,既费时又缺乏通用性。基于深度学习的智能轴承故障诊断方由于具有强大的特征提取能力,避免了繁琐复杂的特征提取工作,但是大多数研究都是在标准数据集下进行的,这意味着模型能够使用足量的数据进行训......
  • OpenCV4中的图像滤波函数定义,原理,以及区别(Python)
    图像滤波1.方框滤波方框滤波的滤波器为矩形,滤波器中的所有元素值均相等。定义如下:dst=boxFilter(src,ddepth,ksize,dst=None,anchor=None,normalize=None,borderType=None)src:输入图像。ddepth:处理后的目标图像的深度,若为-1,则深度与原始图像的深度相同。ks......
  • python自动化——自动化框架常用封装代码复习
    日志模块:importloggingimportosdefcreat_log(name="mylog",level="DEBUG",filename="log.log",sh_level="DEBUG",fh_level="DEBUG"):log=logging.getLogger(name)log.setLevel(level)fh=lo......
  • 分月饼【华为OD机试JAVA&Python&C++&JS题解】
    一.题目-分月饼中秋节,公司分月饼,m个员工,买了n个月饼,m<=n,每个员工至少分1个月饼,但可以分多个,单人分到最多月饼的个数是Max1,单人分到第二多月饼个数是Max2,Max1-Max2<=3,单人分到第n-1多月饼个数是Max(n-1),单人分到第n多月饼个数是Max(n),Max(n-1)–Max(n)<=3,问有多少......
  • Python爬虫是什么?核心概念和原理
    一、爬虫的概念和作用1.1概念:        网络爬虫也叫网络蜘蛛,特指一类自动批量下载网络资源的程序,这是一个比较口语化的定义。更加专业和全面对的定义是:网络爬虫是伪装成客户端与服务端进行数据交互的程序.1.2作用1.2.1数据采集        大数据时代来临......
  • Python面向对象——架构设计【2】
     练习1:打电话请使用面向对象思想描述下列情景:  小明使用手机打电话,还有可能使用座机....classPeople:def__init__(self,name):self.name=namedefcall_up(self,tool):print(self.name,end="")tool.call()cla......
  • Python——Regular Expression(正则表达式)RE
    正则表达式是一种强大的文本处理工具,它使用一种特殊的语法来匹配、查找以及替换字符串中的字符组合。在Python中,正则表达式,"re模块"。英文叫做"RegularExpression"。re模块是Python中用于处理正则表达式的标准库。它提供了多个函数来执行正则表达式的匹配、查找、替换和分割操......