python内存泄漏
python基本运行机制。Python程序运行时不需要编译成二进制代码,而直接从源码运行程序,简单来说是,Python解释器将源码转换为字节码,然后再由解释器来执行这些字节码。
解释器的具体工作:
1 完成模块的加载和链接;
2 将源代码编译为PyCodeObject对象(即字节码),写入内存中,供CPU读取;
3 从内存中读取并执行,结束后将PyCodeObject写回硬盘当中,也就是复制到.pyc或.pyo文件中,以保存当前目录下所有脚本的字节码文件;
- 之后若再次执行该脚本,它先检查【本地是否有上述字节码文件】和【该字节码文件的修改时间是否与其脚本一致】。是就直接执行,否则重复上述步骤。
如果你的程序是死循环,不停歇的代码,下列是需要注意内存的问题。
第一、pillow库的隐患
#内存将发生泄漏
from PIL import Image
im = Image.open('1.jpg')
im.save()
#使用with使程序更安全
from PIL import Image
with open('1.jpg' , 'rb') as open_file:
im = Image.open(open_file)
第二、使用importlib.reload重载模块后带来使用全局变量带来的隐患
假如采取不重启程序方式,自动重新载入修改后的文件,所以需要进行重载模块
'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:579817333
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
#run.py
import importlib
while True:
module_name = importlib.import_module('.', 'test_file')
module_name = importlib.reload(module_name)
result = module_name.main(params)
#test_file.py
global_value = {'dataList':[],
'number':'',}
key = '初始值'
def main(params):
# params携带着此次任务数据
global_value['number'] = params['number']
get_data1(params)
get_data2(params)
return global_value
def get_data1(params):
global key
# 你的程序通过params得到新的数据
data_once = {'每次运行产生的键': '每次运行产生的键值'}
key = '新值'
global_value['dataList'].append(data_once)
def get_data2(params):
# 你的程序通过params和key新的值,得到另一份数据
data_once = {'每次运行产生的新键': '每次运行产生的新键值'}
global_value['dataList'].append(data_once)
上述就会发生一种隐患,以前我觉得垃圾回收机制很靠谱。但是当每一次重载模块时,global_value将使用新的地址,原来的地址还放着上一次的数据,没有被释放掉
就算你在每次循环里添加gc.collect()也不能快速回收删除上一次的数据,导致内存持续增长。。。
我的处理方式是
(1)将global_value这个转移进函数内,通过传参将get_data1和get_data2数据整合在一个变量里
(2)将所有函数放在一个类中,也可以避免全局变量数据存活时间太长
总结,虽然使用全局变量很省事,不用传参,其他函数改变其值再被其他函数调用很方便,却会导致内存泄漏,因为每一次reload时产生的是新的内存地址。
本文来自博客园,作者:I'm_江河湖海,转载请注明原文链接:https://www.cnblogs.com/jhhh/p/16762522.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?