python 内存管理 内存泄漏及排查方案 内存友好的python代码

news2026/5/22 6:33:28
Python 内存管理一、一句话总结Python 的内存管理就是三件事自动分配内存你不用管变量存在哪自动回收垃圾不用的对象自动删掉靠引用计数 分代垃圾回收实现二、核心机制 1引用计数最基础是什么每个对象都有一个引用计数器记录有多少个变量指向它。规则变量指向它 →计数 1变量不再指向它 →计数 -1计数 0→立刻被回收内存释放例子a[1,2,3]# 引用计数 1ba# 引用计数 2dela# 引用计数 1delb# 引用计数 0 → 立即回收优点实时性高不用的对象马上释放内存缺点无法解决循环引用这是最大弱点三、核心机制 2垃圾回收GC解决循环引用什么是循环引用a[]b[]a.append(b)b.append(a)a 引用 bb 引用 a → 互相引用谁也不释放。引用计数永远不会变成 0 → 内存泄漏所以 Python 引入GC垃圾回收专门清理这种情况。四、核心机制 3分代回收GC 工作方式Python 把对象分成 3 代0 代新创建的对象扫描最频繁1 代活过一次GC2 代活得很久的对象扫描最少规则活得越久越不可能被删越新的对象越容易死越要频繁检查效率极高五、内存池机制提升速度Python 不会每次都向操作系统要内存而是自己维护一个内存池小块内存 → 从内存池拿用完归还内存池避免频繁申请/释放速度快很多六、完整流程面试必背创建对象 → 自动分配内存用引用计数跟踪对象被使用次数计数0 →立即释放遇到循环引用→GC分代回收清理小内存使用内存池提升效率七、一句话总结Python 内存管理以引用计数为基础负责实时回收对象通过分代垃圾回收解决循环引用问题并使用内存池减少内存开销提升效率。Python 内存泄漏 排查方案面试实战一、先懂什么是内存泄漏本该被销毁的对象引用一直没断开GC回收不掉内存只涨不跌常见原因循环引用没断干净全局变量一直持有大对象长连接/缓存无限堆积不清空线程、定时器、事件监听忘记关闭第三方库/对象手动内存不释放二、最常见 3 种泄漏场景1. 循环引用引用计数失效a[]b[]a.append(b)b.append(a)# 互相引用计数永远不为0老版本极易泄漏现在Python3 GC能自动清理但大量批量循环引用依旧会卡、占内存2. 全局变量常驻内存cache_list[]# 全局列表defadd_data():foriinrange(100000):cache_list.append([i]*100)# 无限塞永不清空程序运行越久内存越大3. 类实例/闭包持续持有引用deffunc():big_datalist(range(1000000))definner():print(len(big_data))returninner ffunc()# inner闭包一直持有big_data无法释放三、4 大排查工具由简到难1. 内置模块 gc 查看回收情况importgc# 开启调试打印回收详情gc.set_debug(gc.DEBUG_LEAK)# 手动触发垃圾回收gc.collect()# 查看未被回收的泄漏对象print(gc.garbage)gc.garbage里有内容 确定存在泄漏对象2. psutil 实时监控进程内存importpsutilimportosdefget_memory():pidos.getpid()ppsutil.Process(pid)# 单位 MBreturnp.memory_info().rss/1024/1024print(get_memory())循环运行代码观察内存持续上涨不回落泄漏实锤3. objgraph 定位泄漏对象最常用安装pipinstallobjgraph用法importobjgraph# 查看数量最多的对象objgraph.show_most_common_types(limit20)# 查看某个对象的引用链找到是谁还在持有objgraph.show_backrefs(objgraph.find_backref_chain(泄漏对象))直接追踪谁在死死抓住这个对象不放4. memory_profiler 逐行分析内存安装pipinstallmemory-profiler用法frommemory_profilerimportprofileprofiledeftest():# 你的业务代码passtest()运行后逐行显示每行占用内存精准定位爆内存代码四、解决内存泄漏 6 个实用方案主动断开引用不用对象手动赋值Nonebig_dataNone用完及时 del 删除dela,b清空全局缓存/列表cache_list.clear()避免闭包长期持有大对象用完主动解绑手动触发GC定时执行importgc gc.collect()改用弱引用 weakref不想强持有用弱引用不影响回收importweakref objweakref.proxy(原对象)五、面试标准回答Python内存泄漏大多由循环引用、全局常驻对象、闭包强引用、资源未释放导致排查可使用gc模块查看垃圾对象、psutil监控进程内存、objgraph追踪引用链、memory_profiler逐行分析解决方式主动置空引用、及时删除对象、定期清理缓存、使用弱引用、手动触发垃圾回收。六、速记口诀内存只涨不回落大概率是引用锁循环引用全局存闭包持有甩不脱gc查垃圾psutil看涨跌objgraph追源头。如何写出内存友好的 Python 代码谨慎使用全局变量 全局变量通常会进入 GC 的第 2 代长期霸占内存。能放在函数内部的局部变量就不要放在全局。避免死结般的循环引用 如果在设计树状结构或图结构时不可避免地遇到双向引用比如父节点指向子节点子节点又指向父节点请使用标准库中的 weakref弱引用模块。弱引用不会增加对象的引用计数。处理海量数据时使用生成器 如上一篇文章所说生成器按需产出数据不会一次性撑爆内存池。手动触发 GC必要时 在跑完一个极消耗内存的数据清洗脚本后可以通过 import gc; gc.collect() 强制执行一次全量垃圾回收清理内存碎片。深入底层才能在架构和性能优化时游刃有余。Python 绝不仅仅是简单的脚本语言它的内部设计同样充满了权衡与智慧。一、核心原则少创建、晚创建、及时释放、按需加载、避免常驻二、变量与对象优化不用就置空 / del 销毁# 用完大对象立刻解绑large_dataNonedellarge_data优先局部变量少用全局变量全局变量生命周期贯穿整个程序长期占内存局部函数执行完自动释放。避免无意识创建临时大对象# 差生成完整新列表new_list[x*2forxinbig_list]# 好用生成器不占整块内存gen(x*2forxinbig_list)小数据复用对象减少频繁新建循环内不要反复创建大容器提前初始化复用。三、容器选型最关键海量遍历优先用 生成器 / 迭代器列表一次性载入全量数据生成器边用边生成几乎不占内存# 占内存numslist(range(10000000))# 内存友好numsrange(10000000)大量键值存储按需选结构普通字典够用就不用嵌套多层字典固定结构数据用namedtuple/dataclass更省内存数值矩阵优先numpy 数组比原生列表省超多内存大列表及时清空data_list.clear()四、循环写法优化避免循环内嵌套循环生成大中间数据遍历优先 for-in 迭代不要先切片复制# 浪费复制一份新列表foriteminarr[:]:pass# 友好直接遍历原数组foriteminarr:pass分批处理大数据不要一次性全读入文件、日志、数据库数据分页/分块读取而非一次性加载到内存。五、字符串优化大量拼接不用频繁字符串拼接不断新建对象改用列表收集最后join# 差sforiinrange(1000):sstr(i)# 优tmp[]foriinrange(1000):tmp.append(str(i))s.join(tmp)六、资源与IO内存优化文件、网络连接、数据库连接用完必关闭优先with上下文管理器自动释放资源withopen(test.txt,r,encodingutf-8)asf:textf.readline()# 出作用域自动关闭释放日志、缓存设置上限自动淘汰缓存字典/列表加最大长度超出自动丢弃旧数据防止无限膨胀。七、面向对象写法优化类属性少存冗余数据实例只存必要字段冗余计算属性用property动态计算不常驻内存慎用闭包长期捕获大对象闭包会强引用外层大变量导致无法GC回收需要弱关联用 weakref 弱引用不想阻碍垃圾回收使用弱引用不增加引用计数八、GC 与内存回收优化批量处理完数据后手动触发垃圾回收importgc gc.collect()减少循环引用代码写法从源头规避内存泄漏九、第三方库内存技巧Pandas读取csv指定usecols只读取需要列调低数值类型int64→int32、float64→float32图像处理处理完图像数组及时销毁不要全局常驻大图矩阵十、极简背诵总结面试直接说多用生成器迭代器替代列表分批加载大数据优先局部变量严控全局大对象常驻内存资源使用with自动释放用完及时置空删除对象字符串拼接用列表join避免频繁新建字符串精简类实例属性减少冗余存储必要时使用弱引用大数据分页分块处理杜绝一次性全量载入内存。内存友好代码 VS 耗内存代码 对照表一、大数据遍历耗内存写法内存友好写法优势data list(range(10000000))data range(10000000)不生成完整列表迭代取值几乎无内存占用列表推导式[x*2 for x in arr]生成器表达式(x*2 for x in arr)边遍历边计算不存全部结果二、变量作用域耗内存友好写法全局定义大列表/大字典放到函数内作为局部变量长期保留无用大对象del obj/obj None三、循环遍历低效写法优化写法for i in arr[:]:切片复制for i in arr:直接遍历循环内频繁创建空列表外部提前创建循环内清空复用四、字符串拼接浪费内存高效写法s str(i)循环累加列表收集 .join()五、文件读取耗内存友好写法f.read()一次性读整文件for line in f:逐行读取不手动关闭文件with open() as f:上下文管理器六、容器存储笨重写法轻量化写法多层嵌套字典存结构化数据namedtuple/dataclass纯Python列表存海量数值numpy.array统一存储列表无限追加不限制设置最大长度自动清理旧数据七、数据处理错误写法正确写法一次性读取全量数据库数据分页查询、分批拉取图像处理后全局保存原图用完立即销毁图像数组八、引用优化容易泄漏优化方案闭包捕获超大外层变量执行完毕手动解绑变量大量对象强引用绑定weakref弱引用九、垃圾回收放任不管主动优化依赖系统自动GC大批量数据处理后gc.collect()大量循环引用代码重构逻辑减少互相引用十、Pandas专属优化高内存省内存读取所有列usecols指定只读取需要列默认int64/float64向下转型 int32、float32通用极简守则能迭代不存全量能局部不全局能复用不新建能清空不堆积资源用完必释放大对象用完必解绑分批处理大数据拒绝一次性塞满内存

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2633929.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…

网络编程(Modbus进阶)

思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…