Python進(jìn)程使用內(nèi)存后不釋放的解決
背景
使用python進(jìn)行大量的數(shù)據(jù)操作過程中RSS占用(幾個G,Python的GC會頻繁地malloc/free),發(fā)現(xiàn)RSS內(nèi)存不釋放。
- 排查代碼后,沒有發(fā)現(xiàn)內(nèi)存泄露的情況,GC也是默認(rèn)開啟的,甚至代碼將數(shù)據(jù)庫數(shù)據(jù)讀出來遍歷一遍后程序結(jié)束,內(nèi)存一直存在不釋放。
- 使用tracemalloc,objectgraph調(diào)試,Python對象的產(chǎn)生和釋放并沒有啥異常。
- Python的對象內(nèi)存管理是基于引用計數(shù)的(refcnt為0直接decref回收),python內(nèi)存池也沒發(fā)現(xiàn)大內(nèi)存駐留,操作系統(tǒng)brk和mmap也并沒有不釋放內(nèi)存。
在調(diào)測中也發(fā)現(xiàn),這個問題給人的整體感覺不是代碼哪里有問題,查閱相關(guān)資料后,發(fā)現(xiàn)可能是Glibc優(yōu)化問題。
python的內(nèi)存機(jī)制,頻繁通過系統(tǒng)調(diào)用獲取和釋放內(nèi)存對性能消耗很大的,python將對象銷毀后,并沒有立即將這部分內(nèi)存返回給操作系統(tǒng),而是加到了自己維護(hù)的空閑內(nèi)存池中。
從系統(tǒng)層面來看,這步扥內(nèi)存已經(jīng)被python進(jìn)程占用了,但是從python解釋器的角度來看,這部分是free的,可以用于生成新的對象。
那么我們在Python中如何手動分配釋放內(nèi)存?
我們使用進(jìn)程內(nèi)存隔離的能力直接管理內(nèi)存,父進(jìn)程只負(fù)責(zé)進(jìn)程池管理,子進(jìn)程干完事情,直接退出,或過期重新拉起,或者超過內(nèi)存閾值就干掉,就可以了(當(dāng)然最好是業(yè)務(wù)處理不是很頻繁的情況下)。
多進(jìn)程處理參考:multiprocessing --- 基于進(jìn)程的并行 — Python 3.10.0 文檔
Process 類
在 multiprocessing 中,通過創(chuàng)建一個 Process 對象然后調(diào)用它的 start() 方法來生成進(jìn)程。
Process 和 threading.Thread API 相同。
一個簡單的多進(jìn)程程序示例是:
from multiprocessing import Process
def f(name):
print('hello', name)
if __name__ == '__main__':
p = Process(target=f, args=('bob',))
p.start()
p.join()常見問題
實際業(yè)務(wù)中會經(jīng)常用到數(shù)據(jù)庫等長連接的操作,如數(shù)據(jù)庫等,
可能會報如下錯誤:
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
解決辦法
不要將長連接對象通過參數(shù)傳遞,在函數(shù)內(nèi)部鏈接,使得進(jìn)程之間互不影響。
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
django model的update時auto_now不被更新的原因及解決方式
這篇文章主要介紹了django model的update時auto_now不被更新的原因及解決方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-04-04
SQLite5-使用Python來讀寫數(shù)據(jù)庫
這篇文章主要介紹了SQLite5-使用Python來讀寫數(shù)據(jù)庫,數(shù)據(jù)庫的實際應(yīng)用,通常需要與程序結(jié)合起來,通過程序來實現(xiàn)對數(shù)據(jù)庫的訪問和讀寫。本篇先介紹Python語言來調(diào)用SQLite數(shù)據(jù)庫,想具體了解的小伙伴可以參考一下</P><P>2021-12-12
使用DataFrame高效地存放和管理多維數(shù)據(jù)的方法
在數(shù)據(jù)分析領(lǐng)域,處理多維數(shù)據(jù)是日常任務(wù)的核心部分,Python中的Pandas庫提供的DataFrame結(jié)構(gòu),以其靈活性和強(qiáng)大的功能,成為存放和處理多維數(shù)據(jù)的理想選擇,本文將深入探討如何使用DataFrame高效地存放和管理多維數(shù)據(jù),需要的朋友可以參考下2026-02-02
Python matplotlib的使用并自定義colormap的方法
今天小編就為大家分享一篇Python matplotlib的使用并自定義colormap的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-12-12
Python基于正則表達(dá)式實現(xiàn)計算器功能
這篇文章主要介紹了Python基于正則表達(dá)式實現(xiàn)計算器功能,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-07-07
python 爬取免費(fèi)簡歷模板網(wǎng)站的示例
這篇文章主要介紹了python 爬取免費(fèi)簡歷模板網(wǎng)站的示例,幫助大家更好的理解和使用python 爬蟲,感興趣的朋友可以了解下2020-09-09

