(Python)内存管理

前言

内存泄漏在编程中是一个严重的问题,可能导致程序性能下降、系统不稳定甚至崩溃。

目录

危害

风险

动态内存分配

引用计数

内存池

垃圾回收

设计原则


危害

  1. 性能下降:可用内存减少,导致系统频繁进行内存交换,使程序运行速度变慢。
  2. 不稳定:内存耗尽可能导致程序出现异常、崩溃或产生不可预测的结果。
  3. 资源浪费:系统资源被无效占用,影响其他程序的正常运行。

风险

  1. 资源未释放:如果打开的文件、网络连接、数据库连接等资源在使用后没有正确关闭和释放,随着程序的运行,这些未释放的资源会不断累积,占用越来越多的内存。
  2. 无限增长的数据结构:例如,不断向一个列表或字典添加元素,而没有在适当的时候删除不再需要的部分,可能导致数据结构无限增长,消耗大量内存。
  3. 循环引用:对象之间的循环引用可能导致它们的引用计数永远不为零,即使它们不再被程序的其他部分直接使用,也无法被垃圾回收器回收。
  4. 缓存未清理:一些程序为了提高性能会使用缓存,但如果缓存中的数据不再被使用时没有及时清理,也会导致内存占用不断增加。

动态内存分配

在 Python 中,动态内存分配是自动处理的。

当您创建对象(例如列表、字典、类的实例等)时,Python 会自动为这些对象分配所需的内存并为该对象维护一个引用计数。当这些对象不再被引用时(引用计数变为 0 ),Python 的垃圾回收机制会自动回收它们所占用的内存。

引用计数

这是 Python 内存管理的基础机制。每个对象都有一个引用计数,记录着有多少个地方正在引用它。当引用计数变为 0 时,该对象就会被立即释放。

测试范例

引用数统计方法:采用sys模块的getrefcount函数去获取变量的引用数.

python 复制代码
import sys
d = [1, 2, 3]
# 一开始引用次数为1
# 若调用getrefcount函数 引用次数+1 为2
# print(sys.getrefcount(d))
d_dict = {}
person_list = ["张三", "李四", '老王', "杜甫"]

for p in person_list:
    d_dict[p] = d
    print(sys.getrefcount(d))

# 删除变量d_dict后
del d_dict
# 手动触发垃圾回收
print(sys.getrefcount(d))

内存池

这种存储方式通过复用已有的字符串对象,减少了内存分配和释放的操作,提高了性能和内存使用效率。

在 Python 中,以下类型的对象可能会进入内存池:

  1. 小整数对象(范围通常是 [-5, 256] 之间的整数)。
  2. 短字符串(长度较短且经常使用的字符串)。

验证方法

两个字符串变量指向的都是同一个id

python 复制代码
a = "hello"
b = "hello"
print(id(a) == id(b))  

垃圾回收

Python 中主要使用以下两种垃圾回收机制

  1. 引用计数:这是 Python 最基本的垃圾回收机制。每个对象都有一个引用计数,当引用计数变为 0 时,对象就会被立即回收。

  2. 循环引用垃圾回收器:用于处理循环引用导致的内存无法释放的情况。它使用了标记 - 清除算法或者分代回收算法来检测和回收不可达的对象。

标记 - 清除

  1. 标记阶段:从根对象(例如正在运行的函数的局部变量和全局变量)开始,沿着对象之间的引用关系进行遍历,将所有可达的对象进行标记。

  2. 清除阶段:对未被标记的对象进行回收,释放它们所占用的内存空间。

分代回收的策略

将对象分为不同的代(通常是 0 代、1 代、2 代),

并根据不同代的特点和对象的生存时间来决定何时进行垃圾回收,以提高垃圾回收的效率。

设计原则

熟悉 Python 中对象的引用计数机制,那我们的程序设计最好遵守下面的设计原则,以此避免内存泄露的事件.

相关推荐
蹦蹦跳跳真可爱5892 小时前
Python----OpenCV(图像増强——高通滤波(索贝尔算子、沙尔算子、拉普拉斯算子),图像浮雕与特效处理)
人工智能·python·opencv·计算机视觉
nananaij2 小时前
【Python进阶篇 面向对象程序设计(3) 继承】
开发语言·python·神经网络·pycharm
雷羿 LexChien2 小时前
从 Prompt 管理到人格稳定:探索 Cursor AI 编辑器如何赋能 Prompt 工程与人格风格设计(上)
人工智能·python·llm·编辑器·prompt
敲键盘的小夜猫3 小时前
LLM复杂记忆存储-多会话隔离案例实战
人工智能·python·langchain
高压锅_12203 小时前
Django Channels WebSocket实时通信实战:从聊天功能到消息推送
python·websocket·django
胖达不服输4 小时前
「日拱一码」020 机器学习——数据处理
人工智能·python·机器学习·数据处理
吴佳浩4 小时前
Python入门指南-番外-LLM-Fingerprint(大语言模型指纹):从技术视角看AI开源生态的边界与挑战
python·llm·mcp
吴佳浩5 小时前
Python入门指南-AI模型相似性检测方法:技术原理与实现
人工智能·python·llm
叶 落5 小时前
计算阶梯电费
python·python 基础·python 入门
Python大数据分析@6 小时前
Origin、MATLAB、Python 用于科研作图,哪个最好?
开发语言·python·matlab