1. 程式人生 > 程式設計 >Python流程控制常用工具詳解

Python流程控制常用工具詳解

在我們的工作中,我們使用ddagent ver。5作為收集工具,收集和報告託管伺服器的效能指標,並對ddagent進行一定程度的定製。經過多次功能迭代,發現一批線上執行時間長的託管伺服器佔用了太多記憶體。分析問題機器上程序樹中每個節點的佔用情況,可以看出ddagent集合程序的記憶體佔用仍然很高。

我們將學習最基本的流程控制工具,比如

if 條件判斷for 迴圈while 迴圈

作為保證業務系統穩定執行的監控元件,存在記憶體洩漏,這自然是非常嚴重的,所以我們開始了我們的“故障排除之旅”。

if-elif-else 判斷

Python流程控制常用工具詳解

分析

有很多工具可以分析和匯出Python程式的記憶體狀態。在這裡,我們使用pyrasite,它可以附加到正在執行的Python程式,生成記憶體快照,並檢查當前哪些物件型別佔用了多少記憶體,並從大到小排序。

使用命令非常簡單: pyrasite-memory-viewer <PID>,同時會生成一份快照檔案: /tmp/pyrasite-<PID>-objects.json。

由於無法提供真實的生產資料,下面提到的所有資料都來自問題版本在測試環境中執行12小時後的取樣。

在pyrasite提供的Cui檢視中,我們可以清楚地看到字典型別的物件例項佔用的記憶體最多,達到3.4mb,有6621個例項:

Python流程控制常用工具詳解

while 迴圈

While迴圈也是一種常見的迴圈方式。這種迴圈通常以迴圈體類或條件方式結束。它不可能無限期地進行下去。

Python流程控制常用工具詳解

對於洩漏情況,我們有以下事實和猜測:

一個或多個位置持續建立空字典物件,並且無法回收它們,從而導致記憶體洩漏記憶體洩漏量隨時間而增加。在索引收集業務中,洩漏很可能是在每個收集過程中引起的,並在間隔期之後重複觸發我們看不到當前依賴的ddagent版本存在尚未關閉的相關問題,這可能是在我們的定製過程中引入的錯誤

[
 [
 [".../embedded/lib/python2.7/threading.py",774,"__bootstrap","self.__bootstrap_inner()"],[".../embedded/lib/python2.7/threading.py",801,"__bootstrap_inner","self.run()"],[".../modules/monitor/bot/schedule.py",51,"run","task.run()"],[".../modules/monitor/bot/task.py",50,"super(RepeatTask,self).run()"],18,"self.check()"],[".../modules/monitor/checks/collector.py",223,"wrapper","_check.run()"],[".../modules/monitor/checks/__init__.py",630,"self._roll_up_instance_metadata()"],498,"_roll_up_instance_metadata","dict((k,v) for (k,v) in self._instance_metadata))"],[".../modules/monitor/tracer.py",33,"__init__","self.trace_info = traceback.extract_stack()"]
 ],[
 [".../embedded/lib/python2.7/threading.py",...

重播

我們不提“做好設計審查和規範審查”、“加強試驗階段質量檢驗工作”等“老生常談”,也值得我們反思。

要徹底防止和控制記憶體洩漏幾乎是不可能的,像rust這樣的安全程式語言也不能保證程式不會洩漏記憶體。

許多引發記憶體不安全的行為,如陣列訪問越界、訪問釋放後的記憶體等,都可以通過制定更嚴格的程式設計模型(如rust提出的所有權+生命週期規則)甚至資料競爭問題來避免。

然而,觸發記憶體洩漏的行為,如競爭條件,需要開發人員將開發元件和業務規則結合起來。設想一個需要手動觸發重新整理的資料佇列。結果,我們在推送資料時忘記呼叫它。這種記憶體洩漏無法通過任何常規檢查規則來識別。

關鍵字函式是為了更形象地說明傳入引數的位置和具體用法。如果一個函式有四個或五個引數,而且一次傳入的引數太多,那麼很難讓人眼花繚亂。如果key=value用於傳入。

總結

通過本節的學習,我們瞭解了通過if else在不同條件下控制程式碼流和執行不同程式碼。for/while和如何定義函式有兩種不同的迴圈方法,包括函式的返回值和引數傳遞方法、position引數傳遞和向函式傳遞引數時的key=value引數傳遞。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。