(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 中对象的引用计数机制,那我们的程序设计最好遵守下面的设计原则,以此避免内存泄露的事件.

相关推荐
一点媛艺几秒前
Kotlin函数由易到难
开发语言·python·kotlin
魔道不误砍柴功1 小时前
Java 中如何巧妙应用 Function 让方法复用性更强
java·开发语言·python
_.Switch1 小时前
高级Python自动化运维:容器安全与网络策略的深度解析
运维·网络·python·安全·自动化·devops
测开小菜鸟3 小时前
使用python向钉钉群聊发送消息
java·python·钉钉
萧鼎4 小时前
Python并发编程库:Asyncio的异步编程实战
开发语言·数据库·python·异步
学地理的小胖砸4 小时前
【一些关于Python的信息和帮助】
开发语言·python
疯一样的码农4 小时前
Python 继承、多态、封装、抽象
开发语言·python
Python大数据分析@4 小时前
python操作CSV和excel,如何来做?
开发语言·python·excel
黑叶白树4 小时前
简单的签到程序 python笔记
笔记·python
Shy9604185 小时前
Bert完形填空
python·深度学习·bert