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

解决办法

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

总结

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

相关文章

  • 利用Seaborn绘制20个精美的pairplot图

    利用Seaborn绘制20个精美的pairplot图

    本文记录的使用seaborn绘制pairplot图,主要是用来显示两两变量之间的关系(线性或非线性,有无较为明显的相关关系等),感兴趣的可以了解一下
    2022-07-07
  • Python while true实现爬虫定时任务

    Python while true实现爬虫定时任务

    这篇文章主要介绍了Python爬虫定时任务简单实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-06-06
  • python调用java的jar包方法

    python调用java的jar包方法

    今天小编就为大家分享一篇python调用java的jar包方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-12-12
  • Pycharm中切换pytorch的环境和配置的教程详解

    Pycharm中切换pytorch的环境和配置的教程详解

    这篇文章主要介绍了Pycharm中切换pytorch的环境和配置,本文给大家介绍的非常详细,对大家的工作或学习具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-03-03
  • 什么是Python中的顺序表

    什么是Python中的顺序表

    在本篇文章里小编给大家整理了一篇关于Python中顺序表详解的相关知识点以及实例内容,需要的朋友们可以参考下。
    2020-06-06
  • Python装饰器重载内置的使用

    Python装饰器重载内置的使用

    本文主要介绍了Python装饰器重载内置的使用,详细介绍如何创建装饰器,如何使用装饰器来重载内置函数,具有一定的参考价值,感兴趣的可以了解一下
    2024-01-01
  • Python实现对二维码数据进行压缩

    Python实现对二维码数据进行压缩

    当前二维码的应用越来越广泛,包括疫情时期的健康码也是应用二维码的典型案例。本文的目标很明确,就是使用python,实现一张二维码显示更多信息,代码简单实用,感兴趣的可以了解一下
    2023-02-02
  • Python生成二维码的教程详解

    Python生成二维码的教程详解

    作为一名合格的 Python 程序员,在工作中必然会用到二维码相关操作,那如何快速的用 Python 实现呢?别着急,咱们这篇博客就为你解决
    2022-10-10
  • Sublime Text3最新激活注册码分享适用2020最新版 亲测可用

    Sublime Text3最新激活注册码分享适用2020最新版 亲测可用

    这篇文章主要介绍了Sublime Text3最新激活注册码分享亲测3211可用
    2020-11-11
  • Python实现拷贝多个文件到同一目录的方法

    Python实现拷贝多个文件到同一目录的方法

    这篇文章主要介绍了Python实现拷贝多个文件到同一目录的方法,涉及Python针对文件与目录的遍历、复制等相关操作技巧,需要的朋友可以参考下
    2016-09-09

最新评论