Python實(shí)現(xiàn)內(nèi)存泄露排查的示例詳解
一般情況下只有需要長期運(yùn)行的項(xiàng)目才會(huì)去關(guān)注內(nèi)存的增長情況,即使是很小部分的內(nèi)存泄露經(jīng)過長期的運(yùn)行仍然會(huì)產(chǎn)生很大的隱患。
python本身也是支持垃圾的自動(dòng)回收的,但是在特定的情況下也是會(huì)出現(xiàn)內(nèi)存泄露的問題的。
比如對于很多全局的列表(list)/字典(dict)等對象在經(jīng)過不斷的數(shù)據(jù)賦值而沒有進(jìn)行手動(dòng)回收,或者某些對象被不停的循環(huán)引用而不能及時(shí)的進(jìn)行回收等都會(huì)產(chǎn)生內(nèi)存泄露的情況。
一般在python代碼塊的調(diào)試過程中會(huì)使用memory-profiler、filprofiler、objgraph等三種方式進(jìn)行輔助分析,今天這里主要介紹使用objgraph對象提供的函數(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ù)對象。
dict_?=?{
????'姓名':?['Python',?'Java',?'Scala'],
????'年齡':?['21',?'22',?'19']
}
通過objgraph.count()函數(shù),可以統(tǒng)計(jì)出GC中的dict_對象的數(shù)目是多少。
#?Counting?the?number?of?dict_?objects?in?the?GC. print(graph.count(dict_))
和objgraph.count()函數(shù)對應(yīng)的是可以使用by_type返回該對象在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)用以來增加得最多的對象。
#?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é)果中的對象每次增加的數(shù)量來判斷內(nèi)存泄露的相關(guān)情況。
還有一個(gè)比較常用的分析函數(shù)就是graph.show_most_common_types(),可以按照從大到小的方式列出對象實(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的引用圖,可以看出對象為什么不釋放?只是調(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_作為對象進(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)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python請求庫發(fā)送HTTP POST請求的示例代碼
這段代碼使用了Python的requests庫來發(fā)送HTTP POST請求,向本地服務(wù)器的API發(fā)送數(shù)據(jù),并處理響應(yīng),一步步解釋這個(gè)代碼2024-08-08
Python報(bào)錯(cuò)AssertionError:can only test a c
這篇文章主要介紹了Python報(bào)錯(cuò)AssertionError:can only test a child proc問題,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-09-09
Python?OpenCV識(shí)別行人入口進(jìn)出人數(shù)統(tǒng)計(jì)
本文主要介紹了Python?OpenCV識(shí)別行人入口進(jìn)出人數(shù)統(tǒng)計(jì),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧<BR>2023-01-01
Pandas實(shí)現(xiàn)解析JSON數(shù)據(jù)與導(dǎo)出的示例詳解
其實(shí)使用pandas解析JSON?Dataset要方便得多,所以這篇文章主要為大家介紹了Pandas實(shí)現(xiàn)解析JSON數(shù)據(jù)與導(dǎo)出的具體方法,需要的小伙伴可以收藏一下2023-07-07
Python基于數(shù)列實(shí)現(xiàn)購物車程序過程詳解
這篇文章主要介紹了Python基于數(shù)列實(shí)現(xiàn)購物車程序過程詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-06-06

