資源描述:
《分析python中的內(nèi)存泄漏》由會員上傳分享,免費(fèi)在線閱讀,更多相關(guān)內(nèi)容在應(yīng)用文檔-天天文庫。
1、我真正系統(tǒng)地接觸和學(xué)習(xí)黨的基本知識是在這次中級黨校的培訓(xùn)班上。通過學(xué)習(xí),了解了黨的發(fā)展歷程,對黨的性質(zhì)、宗旨、任務(wù)等基本知識有了進(jìn)一步的了解分析Python中的內(nèi)存泄漏 分析Python中的內(nèi)存泄漏 引子 之前一直盲目的認(rèn)為Python不會存在內(nèi)存泄露,但是眼看著上線的項(xiàng)目隨著運(yùn)行時(shí)間的增長而越來越大的內(nèi)存占用,我意識到我寫的程序在發(fā)生內(nèi)存泄露,之前debug過logging模塊導(dǎo)致的內(nèi)存泄露. 目前看來,還有別的地方引起的內(nèi)存泄露.經(jīng)過一天的奮戰(zhàn),終于找到了內(nèi)存泄露的地方,目前項(xiàng)目跑了很長時(shí)間,在業(yè)務(wù)量較小的時(shí)候內(nèi)存還是能回到剛啟動(dòng)的時(shí)候的內(nèi)存占用. 什么情況下不用這么
2、麻煩 如果你的程序只是跑一下就退出大可不必大費(fèi)周章的去查找是否有內(nèi)存泄露,因?yàn)镻ython在退出時(shí)會釋放它所分配的所有內(nèi)存,如果你的程序需要連續(xù)跑很長時(shí)間那么就要仔細(xì)的查找是否產(chǎn)生了內(nèi)存泄露. 場景 如何產(chǎn)生的內(nèi)存泄露呢,項(xiàng)目是一個(gè)TCPserver,每當(dāng)有連接過來時(shí)都會創(chuàng)建一個(gè)連接實(shí)例來進(jìn)行管理,每次斷開時(shí)連接實(shí)例還被占用并沒有釋放.沒有被釋放的原因肯定是因?yàn)橛心硞€(gè)地方對連接實(shí)例的引用沒有釋放,所以隨著時(shí)間的推移,連接創(chuàng)建分配內(nèi)存,對黨的認(rèn)識也有了進(jìn)一步的提高。才真正體會到了中國共產(chǎn)黨的偉大、光榮和正確,更感到只有中國共產(chǎn)黨是全中國最廣大人民利益的忠實(shí)代表我真正系統(tǒng)地接觸和
3、學(xué)習(xí)黨的基本知識是在這次中級黨校的培訓(xùn)班上。通過學(xué)習(xí),了解了黨的發(fā)展歷程,對黨的性質(zhì)、宗旨、任務(wù)等基本知識有了進(jìn)一步的了解連接斷開并沒有釋放掉內(nèi)存,所以就會產(chǎn)生內(nèi)存泄露. 調(diào)試方法 由于不知道具體是哪里引起的內(nèi)存泄露,所以要耐心的一點(diǎn)點(diǎn)調(diào)試. 由于知道了斷開連接時(shí)沒有釋放,所以我就不停的模擬創(chuàng)建連接然后發(fā)送一些包后斷開連接,然后通過下面一行shell來觀察內(nèi)存占用情況: PID=50662;whiletrue;do;psaux
4、grep$PID
5、grep-vgrep
6、awk'{print$5""$6}'>>t;sleep1;done 如果在增長了一定的量后保持住就說明已經(jīng)
7、沒有產(chǎn)生泄露. 同時(shí)可以在對象該釋放的時(shí)候查看對象的引用計(jì)數(shù),通過sys.getrefcount(obj).如果引用計(jì)數(shù)變?yōu)榱?則說明該對象在跳出命名空間后就會被正確回收. 產(chǎn)生原因 項(xiàng)目中兩種情況導(dǎo)致對象沒有被正確回收: 被退出才回收的對象引用 交叉引用 被退出才回收的對象引用 為了追蹤連接所以把連接對象同時(shí)放在一個(gè)列表里,而這個(gè)列表只有在程序退出時(shí)才會被回收,如果不正確處理,那么分配的對象將也會只在程序退出時(shí)才會被回收.對黨的認(rèn)識也有了進(jìn)一步的提高。才真正體會到了中國共產(chǎn)黨的偉大、光榮和正確,更感到只有中國共產(chǎn)黨是全中國最廣大人民利益的忠實(shí)代表我真正系統(tǒng)地接觸和學(xué)
8、習(xí)黨的基本知識是在這次中級黨校的培訓(xùn)班上。通過學(xué)習(xí),了解了黨的發(fā)展歷程,對黨的性質(zhì)、宗旨、任務(wù)等基本知識有了進(jìn)一步的了解 全局變量和類變量都只會在程序退出的時(shí)候才會被回收: _CONNECTIONS=[] #... classConnection(object): def__init__(self,sock,address) pass defserver_loop(): #... sock,address=server_sock.accept() connection=Connection(sock,address) _CONNECTIONS.append(c
9、onnection) #... sock.close() 上面把所有建立的連接都放在全局變量_CONNECTIONS里,如果在關(guān)閉的時(shí)候不從這個(gè)列表里取出(減少引用)則connection對象就不會被回收,則每建立一次連接就會有個(gè)連接對象和連接對象引用的對象不會被回收. 如果把對象放在一個(gè)類屬性里也是一樣的,因?yàn)轭悓ο笤诔绦蛞婚_始就分配,并在程序退出時(shí)才被回收. 解決辦法就是在退出時(shí)從列表(或其他對象)里解除對對象的引用(刪除)對黨的認(rèn)識也有了進(jìn)一步的提高。才真正體會到了中國共產(chǎn)黨的偉大、光榮和正確,更感到只有中國共產(chǎn)黨是全中國最廣大人民利益的忠實(shí)代表我真正系統(tǒng)地接觸和學(xué)
10、習(xí)黨的基本知識是在這次中級黨校的培訓(xùn)班上。通過學(xué)習(xí),了解了黨的發(fā)展歷程,對黨的性質(zhì)、宗旨、任務(wù)等基本知識有了進(jìn)一步的了解 _CONNECTIONS=[] #... classConnection(object): def__init__(self,sock,address) pass defserver_loop(): #... sock,address=server_sock.accept() connection=Connection(sock,