• 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重载模块后带来使用全局变量带来的隐患
    假如采取不重启程序方式,自动重新载入修改后的文件,所以需要进行重载模块

    #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时产生的是新的内存地址。

  • 相关阅读:
    errorC4430解决办法(vs2013)
    c++获取系统当前时间写入txt文件
    黑苹果安装记录(史上最简单的安装教程——小白福利)
    运行vs生成的exe出现应用程序无法正常启动(0x000007b)解决方案(亲测有效)
    数据可视化工具grafans,忘记密码恢复默认admin(基本使用教程)
    opencv任意形状角度透视变换(代码分析清晰)
    opencv两张规格一样的图片拼接(纵向和横向)
    linux3
    linux2
    linux1
  • 原文地址:https://www.cnblogs.com/7134g/p/11516818.html
Copyright © 2020-2023  润新知