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

  • 相关阅读:
    url编码
    客户端安全-xss-1类型介绍
    阿里云扩容教程
    jquery获取和设置表单数据
    uMlet建模工具
    phpstorm的调试工具xdebug
    服务器如何处理http请求
    http基础实战
    协程
    Goroutine(协程)为何能处理大并发?
  • 原文地址:https://www.cnblogs.com/7134g/p/11516818.html
Copyright © 2020-2023  润新知