日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
如何排查Python中的內(nèi)存問題?

發(fā)現(xiàn)應(yīng)用程序內(nèi)存不足是開發(fā)者遇到的糟糕問題之一。內(nèi)存問題一般很難加以診斷和修復(fù),而在Python中尤為困難。Python的自動(dòng)垃圾收集讓您易于上手該語(yǔ)言,但出現(xiàn)問題時(shí),開發(fā)者不知道如何識(shí)別和修復(fù)問題。

成都創(chuàng)新互聯(lián)公司專注于江山企業(yè)網(wǎng)站建設(shè),響應(yīng)式網(wǎng)站設(shè)計(jì),成都做商城網(wǎng)站。江山網(wǎng)站建設(shè)公司,為江山等地區(qū)提供建站服務(wù)。全流程定制制作,專業(yè)設(shè)計(jì),全程項(xiàng)目跟蹤,成都創(chuàng)新互聯(lián)公司專業(yè)和態(tài)度為您提供的服務(wù)

本文介紹如何診斷和修復(fù)開源AutoML庫(kù)EvalML中的內(nèi)存問題。解決內(nèi)存問題沒什么訣竅,但我希望開發(fā)者、尤其是Python開發(fā)者可以了解將來遇到這類問題時(shí)可利用的工具和優(yōu)秀實(shí)踐。

什么是內(nèi)存泄漏?

任何編程語(yǔ)言最重要的功能之一是能夠?qū)⑿畔⒋鎯?chǔ)在計(jì)算機(jī)內(nèi)存中。每當(dāng)您的程序創(chuàng)建一個(gè)新變量,它都會(huì)分配一些內(nèi)存用于存儲(chǔ)該變量的內(nèi)容。

內(nèi)核為程序訪問計(jì)算機(jī)的CPU、內(nèi)存和磁盤存儲(chǔ)等資源定義了接口。每種編程語(yǔ)言提供了要求內(nèi)核分配和釋放內(nèi)存塊供運(yùn)行中的程序使用的方法。

程序要求內(nèi)核留出內(nèi)存塊供使用,但隨后由于錯(cuò)誤或崩潰,程序完成使用該內(nèi)存后從未告訴內(nèi)核,就會(huì)發(fā)生內(nèi)存泄漏。在這種情況下,內(nèi)核將繼續(xù)認(rèn)為被遺忘的內(nèi)存塊仍被運(yùn)行中的程序使用,其他程序無法訪問這些內(nèi)存塊。

如果運(yùn)行程序時(shí)同樣的泄漏一再發(fā)生,被遺忘的內(nèi)存總量會(huì)變得很龐大,因而消耗計(jì)算機(jī)的大部分內(nèi)存!在這種情況下,如果程序隨后嘗試請(qǐng)求更多內(nèi)存,內(nèi)核會(huì)拋出“內(nèi)存不足”錯(cuò)誤,程序?qū)⑼V惯\(yùn)行,換句話說“崩潰”。

因此,找到并修復(fù)所編寫的程序中的內(nèi)存泄漏很重要,否則程序最終可能會(huì)耗盡內(nèi)存并崩潰,或者可能導(dǎo)致其他程序崩潰。

第1步:確定是內(nèi)存問題

應(yīng)用程序崩潰的原因有很多:也許運(yùn)行代碼的服務(wù)器崩潰了,也許代碼本身存在邏輯錯(cuò)誤,所以確定眼前的問題是內(nèi)存問題很重要。

EvalML性能測(cè)試悄然崩潰。突然,服務(wù)器停止記錄進(jìn)度,作業(yè)悄然停止。服務(wù)器日志會(huì)顯示編程錯(cuò)誤引起的任何堆棧追蹤,所以我有預(yù)感:崩潰是作業(yè)耗用所有的可用內(nèi)存引起的。

我又重新進(jìn)行了性能測(cè)試,但這次啟用了Python的內(nèi)存分析器,以獲取內(nèi)存使用情況圖。測(cè)試再次崩潰,當(dāng)我查看內(nèi)存圖時(shí),發(fā)現(xiàn)了該圖:

圖1.性能測(cè)試的內(nèi)存使用情況

內(nèi)存使用情況逐漸保持穩(wěn)定,但隨后達(dá)到8 GB!我知道應(yīng)用服務(wù)器有8GB 的內(nèi)存,所以該圖證實(shí)我們耗盡了內(nèi)存。此外,內(nèi)存穩(wěn)定時(shí),我們使用約4 GB的內(nèi)存,但之前版本的EvalML使用約2 GB的內(nèi)存。由于某種原因,當(dāng)前版本使用的內(nèi)存是平常的大約兩倍。

現(xiàn)在需要找出原因。

第2步:用極簡(jiǎn)示例在本地重現(xiàn)內(nèi)存問題

查明內(nèi)存問題的原因需要大量實(shí)驗(yàn)和迭代,因?yàn)榇鸢竿ǔ2⒉幻黠@。如果是這樣,您可能不會(huì)將其寫入代碼!出于這個(gè)原因,我認(rèn)為用盡可能少的代碼行重現(xiàn)問題很重要。這個(gè)極簡(jiǎn)示例使您可以在修改代碼時(shí)在分析器下快速運(yùn)行它,查看是否取得進(jìn)展。

我憑經(jīng)驗(yàn)知道,大概在我看到大峰值時(shí),應(yīng)用程序運(yùn)行含有150萬(wàn)行的出租車數(shù)據(jù)集。我將應(yīng)用程序精簡(jiǎn)至僅運(yùn)行該數(shù)據(jù)集的部分。我看到了類似上述的峰值,但這次內(nèi)存使用量達(dá)到了10 GB!

見此情形,我知道有一個(gè)足夠好的極簡(jiǎn)示例可深入研究。

圖2. 出租車數(shù)據(jù)集本地重現(xiàn)的內(nèi)存使用情況

第3步:找到分配最多內(nèi)存的代碼行

一旦將問題隔離到盡可能小的代碼塊,我們可以看到程序在何處分配最多的內(nèi)存。這便于您重構(gòu)代碼和修復(fù)問題。

filprofiler是個(gè)出色的Python工具。它顯示應(yīng)用程序中每一行代碼在內(nèi)存使用高峰時(shí)的內(nèi)存分配情況。這是本地示例的輸出結(jié)果:

圖3. fil-profile的輸出

filprofiler根據(jù)內(nèi)存分配情況對(duì)應(yīng)用程序中的代碼行(以及依賴項(xiàng)的代碼)進(jìn)行排名。線越長(zhǎng)越紅,分配的內(nèi)存越多。

分配最多內(nèi)存的代碼行用來創(chuàng)建pandas數(shù)據(jù)幀(pandas/core/algorithms.py和pandas/core/internal/managers.py),數(shù)據(jù)量達(dá)4GB!我在這里截?cái)嗔薴ilprofiler的輸出,但它能夠?qū)andas代碼追溯到用EvalML來創(chuàng)建Pandas數(shù)據(jù)幀的代碼。

是的,EvalML創(chuàng)建Pandas數(shù)據(jù)幀,但這些數(shù)據(jù)幀在整個(gè)AutoML算法中都是短暫的,一旦不再使用就應(yīng)該被釋放。由于實(shí)際情況并非如此,加上這些數(shù)據(jù)幀在內(nèi)存中的時(shí)間足夠長(zhǎng),我認(rèn)為最新版本帶來了內(nèi)存泄漏。

第4步:識(shí)別泄漏對(duì)象

在Python中,泄漏對(duì)象是使用完成后沒有被Python的垃圾收集器釋放的對(duì)象。由于 Python使用引用計(jì)數(shù)作為主要的垃圾收集算法之一,這些泄漏對(duì)象通常是由對(duì)象占有引用時(shí)間過長(zhǎng)引起的。

這類對(duì)象很難找到,但可以用一些Python工具簡(jiǎn)化搜尋。第一個(gè)工具是垃圾收集器的gc.DEBUG_SAVEALL標(biāo)志。若設(shè)置該標(biāo)志,垃圾收集器將無法訪問的對(duì)象存儲(chǔ)在gc.garbage列表中。這讓您可以進(jìn)一步研究這些對(duì)象。

第二個(gè)工具是objgraph庫(kù)。一旦對(duì)象在gc.garbage列表中,我們可以根據(jù)pandas數(shù)據(jù)幀過濾該列表,并使用objgraph查看哪些其他對(duì)象引用這些數(shù)據(jù)幀、將它們保存在內(nèi)存中。

這是我在可視化其中一個(gè)數(shù)據(jù)幀后看到的對(duì)象圖的一個(gè)子集:

圖4. Pandas數(shù)據(jù)幀使用內(nèi)存圖,顯示導(dǎo)致內(nèi)存泄漏的循環(huán)引用

這就是我要找的確鑿證據(jù)!數(shù)據(jù)幀通過創(chuàng)建循環(huán)引用的PandasTableAccessor對(duì)自身進(jìn)行引用,因此這會(huì)將對(duì)象保留在內(nèi)存中,直到Python的垃圾收集器運(yùn)行并釋放它。(可以通過dict、PandasTableAccessor、dict和_dataframe 追蹤循環(huán)。)這對(duì)EvalML來說有問題,因?yàn)槔占鲗⑦@些數(shù)據(jù)幀保存在內(nèi)存中的時(shí)間太長(zhǎng),以至于我們耗盡內(nèi)存!

我能夠?qū)andasTableAccessor追溯到Woodwork庫(kù),并將該問題提交給維護(hù)者。他們?cè)谛掳姹局行迯?fù)后,向pandas存儲(chǔ)庫(kù)提交了相關(guān)的問題單,這個(gè)例子表明了開源生態(tài)系統(tǒng)中的合作。

Woodwork更新發(fā)布后,我可視化同一個(gè)數(shù)據(jù)幀的對(duì)象圖,循環(huán)消失了!

圖5.woodwork升級(jí)后pandas數(shù)據(jù)幀的對(duì)象圖。不再有循環(huán)!

第5步:驗(yàn)證修復(fù)是否有效

我在EvalML中升級(jí)Woodwork 版本后,測(cè)量了應(yīng)用程序的內(nèi)存使用情況。結(jié)果發(fā)現(xiàn),內(nèi)存使用量現(xiàn)在不到過去的一半!

圖6. 修復(fù)后性能測(cè)試的內(nèi)存使用情況


網(wǎng)站標(biāo)題:如何排查Python中的內(nèi)存問題?
網(wǎng)頁(yè)鏈接:http://www.dlmjj.cn/article/dhgodjs.html