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爬虫之urllib2使用指南

    零基础写python爬虫之urllib2使用指南

    urllib2是Python的一个获取URLs(Uniform Resource Locators)的组件。他以urlopen函数的形式提供了一个非常简单的接口,下面我们用实例讲解他的使用方法
    2014-11-11
  • 对python mayavi三维绘图的实现详解

    对python mayavi三维绘图的实现详解

    今天小编就为大家分享一篇对python mayavi三维绘图的实现详解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-01-01
  • django model的update时auto_now不被更新的原因及解决方式

    django model的update时auto_now不被更新的原因及解决方式

    这篇文章主要介绍了django model的update时auto_now不被更新的原因及解决方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-04-04
  • SQLite5-使用Python来读写数据库

    SQLite5-使用Python来读写数据库

    这篇文章主要介绍了SQLite5-使用Python来读写数据库,数据库的实际应用,通常需要与程序结合起来,通过程序来实现对数据库的访问和读写。本篇先介绍Python语言来调用SQLite数据库,想具体了解的小伙伴可以参考一下</P><P>
    2021-12-12
  • 使用DataFrame高效地存放和管理多维数据的方法

    使用DataFrame高效地存放和管理多维数据的方法

    在数据分析领域,处理多维数据是日常任务的核心部分,Python中的Pandas库提供的DataFrame结构,以其灵活性和强大的功能,成为存放和处理多维数据的理想选择,本文将深入探讨如何使用DataFrame高效地存放和管理多维数据,需要的朋友可以参考下
    2026-02-02
  • Python matplotlib的使用并自定义colormap的方法

    Python matplotlib的使用并自定义colormap的方法

    今天小编就为大家分享一篇Python matplotlib的使用并自定义colormap的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-12-12
  • 老生常谈python之鸭子类和多态

    老生常谈python之鸭子类和多态

    下面小编就为大家带来一篇老生常谈python之鸭子类和多态。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-06-06
  • Python基于正则表达式实现计算器功能

    Python基于正则表达式实现计算器功能

    这篇文章主要介绍了Python基于正则表达式实现计算器功能,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-07-07
  • Python多线程实例教程

    Python多线程实例教程

    这篇文章主要介绍了Python多线程,对比了新旧版本的Python在实现多线程的特点,并采用threading模块的实例来讲述了多线程的技巧,需要的朋友可以参考下
    2014-09-09
  • python 爬取免费简历模板网站的示例

    python 爬取免费简历模板网站的示例

    这篇文章主要介绍了python 爬取免费简历模板网站的示例,帮助大家更好的理解和使用python 爬虫,感兴趣的朋友可以了解下
    2020-09-09

最新评论