Python进程使用内存后不释放的解决

 更新时间:2023年11月07日 11:01:32   作者:Rnan-prince  
这篇文章主要介绍了Python进程使用内存后不释放的解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

背景

使用python进行大量的数据操作过程中RSS占用(几个G,Python的GC会频繁地malloc/free),发现RSS内存不释放。

  • 排查代码后,没有发现内存泄露的情况,GC也是默认开启的,甚至代码将数据库数据读出来遍历一遍后程序结束,内存一直存在不释放。
  • 使用tracemalloc,objectgraph调试,Python对象的产生和释放并没有啥异常。
  • Python的对象内存管理是基于引用计数的(refcnt为0直接decref回收),python内存池也没发现大内存驻留,操作系统brk和mmap也并没有不释放内存。

在调测中也发现,这个问题给人的整体感觉不是代码哪里有问题,查阅相关资料后,发现可能是Glibc优化问题。

python的内存机制,频繁通过系统调用获取和释放内存对性能消耗很大的,python将对象销毁后,并没有立即将这部分内存返回给操作系统,而是加到了自己维护的空闲内存池中。

从系统层面来看,这步扥内存已经被python进程占用了,但是从python解释器的角度来看,这部分是free的,可以用于生成新的对象。

那么我们在Python中如何手动分配释放内存?

我们使用进程内存隔离的能力直接管理内存,父进程只负责进程池管理,子进程干完事情,直接退出,或过期重新拉起,或者超过内存阈值就干掉,就可以了(当然最好是业务处理不是很频繁的情况下)。

多进程处理参考:multiprocessing --- 基于进程的并行 — Python 3.10.0 文档

Process 类

在 multiprocessing 中,通过创建一个 Process 对象然后调用它的 start() 方法来生成进程。 

Process 和 threading.Thread API 相同。

一个简单的多进程程序示例是:

from multiprocessing import Process
 
def f(name):
    print('hello', name)
 
if __name__ == '__main__':
    p = Process(target=f, args=('bob',))
    p.start()
    p.join()

常见问题 

实际业务中会经常用到数据库等长连接的操作,如数据库等,

可能会报如下错误:

ERROR:base.py:Line 705:_finalize_fairy:Exception during reset or similar
 
Traceback (most recent call last):
  File "/home/tsalazar/.cache/pypoetry/virtualenvs/ufos--PZ7y9g--py3.8/lib/python3.8/site-packages/sqlalchemy/pool/base.py", line 697, in _finalize_fairy
    fairy._reset(pool)
 
  File "/home/tsalazar/.cache/pypoetry/virtualenvs/ufos--PZ7y9g--py3.8/lib/python3.8/site-packages/sqlalchemy/pool/base.py", line 893, in _reset
    pool._dialect.do_rollback(self)
 
  File "/home/tsalazar/.cache/pypoetry/virtualenvs/ufos--PZ7y9g--py3.8/lib/python3.8/site-packages/sqlalchemy/engine/default.py", line 558, in do_rollback
    dbapi_connection.rollback()
 
psycopg2.OperationalError: SSL error: decryption failed or bad record mac

解决办法

不要将长连接对象通过参数传递,在函数内部链接,使得进程之间互不影响。 

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • python计算邻接矩阵的实现示例

    python计算邻接矩阵的实现示例

    邻接矩阵是一种常见的图表示方法,本文主要介绍了python计算邻接矩阵的实现示例,具有一定的参考价值,感兴趣的可以了解一下
    2023-11-11
  • 详解Python3的TFTP文件传输

    详解Python3的TFTP文件传输

    本篇内容给大家详细讲述了Python3的TFTP文件传输的相关知识点,有需要的朋友可以参考下。
    2018-06-06
  • Python3加密解密库Crypto的RSA加解密和签名/验签实现方法实例

    Python3加密解密库Crypto的RSA加解密和签名/验签实现方法实例

    这篇文章主要介绍了Python3加密解密库Crypto的RSA加解密和签名/验签实现方法实例,需要的朋友可以参考下
    2020-02-02
  • 使用Python制作一个批量查询搜索排名工具

    使用Python制作一个批量查询搜索排名工具

    这篇文章主要为大家详细介绍了如何使用Python制作一个批量查询搜索排名工具,并且不需要花费任何费用,装上python开发环境即可,需要的可以参考一下
    2023-06-06
  • Python机器学习应用之基于LightGBM的分类预测篇解读

    Python机器学习应用之基于LightGBM的分类预测篇解读

    这篇文章我们继续学习一下GBDT模型的另一个进化版本:LightGBM,LigthGBM是boosting集合模型中的新进成员,由微软提供,它和XGBoost一样是对GBDT的高效实现,原理上它和GBDT及XGBoost类似,都采用损失函数的负梯度作为当前决策树的残差近似值,去拟合新的决策树
    2022-01-01
  • Python实现截图生成符合markdown的链接

    Python实现截图生成符合markdown的链接

    之前是用的是typora来写的文章,最近typora最近开始收费了,所以就不想用了,于是找到了一个替代品MarkText。本文将介绍如何通过Python实现截图自动生成符合markdown的链接,感兴趣的可以了解一下
    2022-01-01
  • python将人民币转换大写的脚本代码

    python将人民币转换大写的脚本代码

    python将人民币转换大写的代码,有需要的朋友可以参考下
    2013-02-02
  • Python连接Mysql进行增删改查的示例代码

    Python连接Mysql进行增删改查的示例代码

    这篇文章主要介绍了Python连接Mysql进行增删改查的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-08-08
  • Python批量模糊匹配的3种方法实例

    Python批量模糊匹配的3种方法实例

    模糊匹配可以算是现代编辑器的一个必备特性了,它所做的就是根据用户输入的部分内容,猜测用户想要的文件名,并提供一个推荐列表供用户选择,下面这篇文章主要给大家介绍了关于Python批量模糊匹配的3种方法,需要的朋友可以参考下
    2022-03-03
  • Python实现连通域标记算法

    Python实现连通域标记算法

    如果把图像分为前景和背景两部分,那么连通域就是连通在一起的前景,这种关系对于二值图像来说比较明显,下面我们就来了解一下连通域标记算法原理及其Python实现吧
    2023-12-12

最新评论