Python實(shí)現(xiàn)內(nèi)存泄露排查的示例詳解
一般情況下只有需要長(zhǎng)期運(yùn)行的項(xiàng)目才會(huì)去關(guān)注內(nèi)存的增長(zhǎng)情況,即使是很小部分的內(nèi)存泄露經(jīng)過長(zhǎng)期的運(yùn)行仍然會(huì)產(chǎn)生很大的隱患。
python本身也是支持垃圾的自動(dòng)回收的,但是在特定的情況下也是會(huì)出現(xiàn)內(nèi)存泄露的問題的。
比如對(duì)于很多全局的列表(list)/字典(dict)等對(duì)象在經(jīng)過不斷的數(shù)據(jù)賦值而沒有進(jìn)行手動(dòng)回收,或者某些對(duì)象被不停的循環(huán)引用而不能及時(shí)的進(jìn)行回收等都會(huì)產(chǎn)生內(nèi)存泄露的情況。
一般在python代碼塊的調(diào)試過程中會(huì)使用memory-profiler、filprofiler、objgraph等三種方式進(jìn)行輔助分析,今天這里主要介紹使用objgraph對(duì)象提供的函數(shù)接口來進(jìn)行內(nèi)存泄露的分析。
objgraph是python的非標(biāo)準(zhǔn)模塊,因此需要使用pip的方式安裝一下。
pip?install?objgraph
更多詳細(xì)的介紹可以訪問下面的官方地址進(jìn)行查看。
接下來就可以直接將objgraph導(dǎo)入到我們的代碼塊中進(jìn)行使用了。
#?Importing?the?objgraph?module?and?renaming?it?to?graph. import?objgraph?as?graph
這里初始化一組字典類型的數(shù)據(jù)對(duì)象。
dict_?=?{ ????'姓名':?['Python',?'Java',?'Scala'], ????'年齡':?['21',?'22',?'19'] }
通過objgraph.count()函數(shù),可以統(tǒng)計(jì)出GC中的dict_對(duì)象的數(shù)目是多少。
#?Counting?the?number?of?dict_?objects?in?the?GC. print(graph.count(dict_))
和objgraph.count()函數(shù)對(duì)應(yīng)的是可以使用by_type返回該對(duì)象在GC中的列表,若是GC返回的為空的列表說明已經(jīng)被回收了。
#?Returning?a?list?of?dict_?objects?in?the?GC. print(graph.by_type(dict_))
在統(tǒng)計(jì)內(nèi)存泄露時(shí)比較好用的函數(shù)就是graph.show_growth()函數(shù),可以統(tǒng)計(jì)自上次調(diào)用以來增加得最多的對(duì)象。
#?Showing?the?growth?of?objects?in?the?memory?since?the?last?time?it?was?called. print(graph.show_growth()) #?function???????????????????????3013?????+3013 #?tuple??????????????????????????1463?????+1463 #?dict???????????????????????????1417?????+1417 #?wrapper_descriptor?????????????1178?????+1178 #?ReferenceType???????????????????883??????+883 #?method_descriptor???????????????814??????+814 #?builtin_function_or_method??????794??????+794 #?getset_descriptor???????????????514??????+514 #?type????????????????????????????463??????+463 #?list????????????????????????????436??????+436 #?None
可以根據(jù)返回結(jié)果中的對(duì)象每次增加的數(shù)量來判斷內(nèi)存泄露的相關(guān)情況。
還有一個(gè)比較常用的分析函數(shù)就是graph.show_most_common_types(),可以按照從大到小的方式列出對(duì)象實(shí)例比較多的情況。
#?Showing?the?most?common?types?of?objects?in?the?memory. print(graph.show_most_common_types()) #?function???????????????????3013 #?tuple??????????????????????1463 #?dict???????????????????????1417 #?wrapper_descriptor?????????1178 #?ReferenceType??????????????883 #?method_descriptor??????????814 #?builtin_function_or_method?794 #?getset_descriptor??????????514 #?type???????????????????????463 #?list???????????????????????436 #?None
最后一個(gè)比較使用函數(shù)就是show_backrefs函數(shù),使用它可以分析出內(nèi)存泄露的原因是什么。
它會(huì)生成一張有關(guān)objs的引用圖,可以看出對(duì)象為什么不釋放?只是調(diào)用該函數(shù)時(shí)的參數(shù)比較多,下面是該函數(shù)的接口。
#?def?show_backrefs(objs,?max_depth=3,?extra_ignore=(),?filter=None,?too_many=10, #???????????????????highlight=None,?filename=None,?extra_info=None, #???????????????????refcounts=False,?shortnames=True,?output=None, #???????????????????extra_node_attrs=None):
我們還是和上面一樣使用dict_作為對(duì)象進(jìn)行分析。
#?Showing?the?back?references?of?the?dict_?object. graph.show_backrefs(dict_)
執(zhí)行完成后dot類型的圖片已經(jīng)生成了,發(fā)現(xiàn)出現(xiàn)了下面的錯(cuò)誤,意思是沒有發(fā)現(xiàn)支持dot的圖像組件。
#?Graph?written?to?C:\Users\86159\AppData\Local\Temp\objgraph-dkqm85f0.dot?(4?nodes) #?Graph?viewer?(xdot)?and?image?renderer?(dot)?not?found,?not?doing?anything?else
可以使用pip的方式分別安裝graphviz xdot,這兩個(gè)python的非標(biāo)準(zhǔn)模塊。
pip?install?graphviz?xdot
若是查看.dot決策樹圖像可以使用graphviz工具,可以到下面地址進(jìn)行下載安裝。
https://graphviz.org/download/
安裝完成后配置環(huán)境變量,然后重啟開發(fā)工具(這里使用的是pycharm)即可。
到此這篇關(guān)于Python實(shí)現(xiàn)內(nèi)存泄露排查的示例詳解的文章就介紹到這了,更多相關(guān)Python內(nèi)存泄露排查內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Flask與數(shù)據(jù)庫的交互插件Flask-Sqlalchemy的使用
在構(gòu)建Web應(yīng)用時(shí),與數(shù)據(jù)庫的交互是必不可少的部分,本文主要介紹了Flask與數(shù)據(jù)庫的交互插件Flask-Sqlalchemy的使用,具有一定的參考價(jià)值,感興趣的可以了解一下2024-03-03Python操作mysql數(shù)據(jù)庫實(shí)現(xiàn)增刪查改功能的方法
這篇文章主要介紹了Python操作mysql數(shù)據(jù)庫實(shí)現(xiàn)增刪查改功能的方法,涉及Python針對(duì)mysql數(shù)據(jù)庫的連接、增刪改查等相關(guān)操作技巧,需要的朋友可以參考下2018-01-01python 導(dǎo)入數(shù)據(jù)及作圖的實(shí)現(xiàn)
今天小編就為大家分享一篇python 導(dǎo)入數(shù)據(jù)及作圖的實(shí)現(xiàn),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-12-12python中自定義異常/raise關(guān)鍵字拋出異常的案例解析
在編程過程中合理的使用異常可以使得程序正常的執(zhí)行,本篇文章給大家介紹python中自定義異常/raise關(guān)鍵字拋出異常案例解析,需要的朋友可以參考下2024-01-01pygame用blit()實(shí)現(xiàn)動(dòng)畫效果的示例代碼
這篇文章主要介紹了pygame用blit()實(shí)現(xiàn)動(dòng)畫效果的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-05-05python中讀取txt文件時(shí)split()函數(shù)的妙用
這篇文章主要介紹了python中讀取txt文件時(shí)split()函數(shù)的妙用,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-11-11