📝 面试求职: 「面试试题小程序」 ,内容涵盖 测试基础、Linux操作系统、MySQL数据库、Web功能测试、接口测试、APPium移动端测试、Python知识、Selenium自动化测试相关、性能测试、性能测试、计算机网络知识、Jmeter、HR面试,命中率杠杠的。(大家刷起来…)
📝 职场经验干货:
Python 的垃圾回收机制是确保程序在运行时有效管理内存的重要组成部分。简单来说,垃圾回收机制的主要目的是自动管理内存,回收不再使用的对象,以避免内存泄漏。以下是 Python 垃圾回收机制的几个关键组成部分:
1. 引用计数(Reference Counting)
Python 中最基本的垃圾回收方式是引用计数。每个对象都有一个计数器,记录着有多少个引用指向该对象。当一个对象的引用计数降为 0 时,表示这个对象不再被使用,Python 的内存管理器会立即回收它所占用的内存。具体来说,引用计数的流程如下:
-
创建对象时,引用计数初始为 1。
-
每当有一个新的引用指向该对象时,引用计数加 1。
-
每当引用被删除或指向其他对象时,引用计数减 1。
-
当引用计数为 0 时,自动释放该对象的内存。
2. 循环引用
引用计数有一个明显的缺点,就是无法处理循环引用。循环引用发生在两个或多个对象互相引用而形成环形结构,即使它们的引用计数可能不为 0,这些对象也无法被回收。例如:
class Node:
def __init__(self):
self.ref = None
a = Node()
b = Node()
a.ref = b
b.ref = a # 形成循环引用
在这个例子中,即使 a
和 b
不再被任何其他对象引用,它们仍然无法被回收,因为它们互相引用,导致引用计数不能降到 0。
3. 垃圾回收(Garbage Collection)
为了处理循环引用,Python还实现了一个额外的垃圾回收机制,使用的主要是标记-清除(Mark-and-Sweep)算法。这个机制的基本流程是:
-
标记阶段:从根对象(通常是全局变量和局部变量)开始,遍历所有可达的对象,并将它们标记为存活的。
-
清除阶段:遍历所有对象,回收那些未被标记(不再存活)的对象所占用的内存。
4. 垃圾回收的触发
Python 的垃圾回收并不是在每次对象没有引用时立即执行的。它会在特定的条件下,比如:
-
创建了新的对象,并且当前的内存已达到一定的阈值。
-
手动调用
gc.collect()
,这会强制进行垃圾回收。
5. 使用 gc
模块
Python 提供了 gc
模块,允许程序员控制和管理垃圾回收的行为。这个模块提供了几个重要的函数,例如:
-
gc.collect()
:手动触发垃圾回收。 -
gc.get_count()
:获取当前的垃圾回收计数。 -
gc.get_objects()
:返回所有被跟踪的对象的列表
6. 检测 Python 垃圾回收
要确定 Python 实际上进行了垃圾回收,可以使用 gc
模块中的一些函数:
-
启用垃圾回收: 首先,确保垃圾回收是启用的,使用以下代码检查:
import gc
print(gc.isenabled()) # 返回 True,表示垃圾回收是启用的
统计活动对象:使用 gc.get_count() 可以查看当前的垃圾回收器的状态
print(gc.get_count()) # 返回一个元组,包含当前的垃圾回收计数
手动触发并检查回收: 你可以调用 gc.collect()
来手动触发垃圾回收,并通过返回值了解回收的结果。例如:
collected = gc.collect() # 返回被回收的对象数量
print(f"Collected {collected} objects.")
调试信息: 可以通过设置调试模式来获取更详细的垃圾回收信息:
gc.set_debug(gc.DEBUG_LEAK | gc.DEBUG_SAVEALL)
7. 垃圾回收参数的设置
gc
模块中有gc.set_threshold(threshold0, threshold1 = None, threshold2 = None)
函数。这个函数用于设置垃圾回收的阈值,这对理解 Python 的垃圾回收机制很重要。
Python 将对象分为三代。
第0代:新创建的对象放在第 0 代。当第 0 代对象经过一定次数的垃圾回收后还存活,就会被移到第 1 代。
第 1 代:第一代对象在经过多次垃圾回收后还存活,就会被移到第 2 代。
第 2 代:第2代对象是存活时间最久的对象。这种分代的垃圾回收策略可以提高垃圾回收的效率,因为大多数对象都是短期存活的,频繁地对所有对象进行全面扫描会比较耗时,通过分代可以优先处理最有可能成为垃圾的新对象。
threshold0:
threshold0
时,垃圾回收机制会被触发来处理最年轻(第 0 代)的对象。这是一个整数参数。例如,如果threshold0
设置为 700,当第 0 代对象的数量净增长达到 700 时,就会对第 0 代对象进行垃圾回收。
threshold1(可选):
当第 0 代对象被扫描的次数超过threshold1
后,会触发对第 1 代对象(稍老一些的对象)的垃圾回收。如果不提供这个参数,Python 会使用一个默认值。这也是一个整数参数。比如,默认情况下threshold1
可能是 10,当第 0 代对象已经被扫描了 10 次后,就会检查第 1 代对象的垃圾回收情况。
threshold2(可选):
threshold2
后,会触发对第 2 代对象(最老的对象)的垃圾回收。同样,如果不提供这个参数,Python 会使用默认值。它同样是一个整数参数。例如,默认的threshold2
可能是 10,当第 1 代对象已经被扫描了 10 次后,就会检查第 2 代对象是否需要进行垃圾回收。
总结
Python 的垃圾回收机制结合了引用计数和标记-清除算法,既能及时回收不再使用的对象内存,又能处理复杂的循环引用问题。了解这些机制有助于编写更高效的 Python 程序,避免内存泄漏和资源浪费。
最后: 下方这份完整的软件测试视频教程已经整理上传完成,需要的朋友们可以自行领取【保证100%免费】