Python流程控制經常使用工具和函數定義

在咱們的工做中,咱們使用ddagent ver。5做爲收集工具,收集和報告託管服務器的性能指標,並對ddagent進行必定程度的定製。通過屢次功能迭代,發現一批在線運行時間長的託管服務器佔用了太多內存。分析問題機器上進程樹中每一個節點的佔用狀況,能夠看出ddagent集合進程的內存佔用仍然很高。java

咱們將學習最基本的流程控制工具,好比python

  • if 條件判斷
  • for 循環
  • while 循環

做爲保證業務系統穩定運行的監控組件,存在內存泄漏,這天然是很是嚴重的,因此咱們開始了咱們的「故障排除之旅」。編程

if-elif-else 判斷

分析

有不少工具能夠分析和導出Python程序的內存狀態。在這裏,咱們使用pyrasite,它能夠附加到正在運行的Python程序,生成內存快照,並檢查當前哪些對象類型佔用了多少內存,並從大到小排序。json

使用命令很是簡單: pyrasite-memory-viewer <PID> ,同時會生成一份快照文件: /tmp/pyrasite-<PID>-objects.json 。bootstrap

因爲沒法提供真實的生產數據,下面提到的全部數據都來自問題版本在測試環境中運行12小時後的採樣。數組

在pyrasite提供的Cui視圖中,咱們能夠清楚地看到字典類型的對象實例佔用的內存最多,達到3.4mb,有6621個實例:安全

 

 while 循環服務器

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

 

 對於泄漏狀況,咱們有如下事實和猜想:python2.7

  • 一個或多個位置持續建立空字典對象,而且沒法回收它們,從而致使內存泄漏
  • 內存泄漏量隨時間而增長。在索引收集業務中,泄漏極可能是在每一個收集過程當中引發的,並在間隔期以後重複觸發
  • 咱們看不到當前依賴的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,"run","super(RepeatTask, self).run()"],
    [".../modules/monitor/bot/task.py",18,"run","self.check()"],
    [".../modules/monitor/checks/collector.py",223,"wrapper","_check.run()"],
    [".../modules/monitor/checks/__init__.py",630,"run","self._roll_up_instance_metadata()"],
    [".../modules/monitor/checks/__init__.py",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",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,"run","super(RepeatTask, self).run()"],
    [".../modules/monitor/bot/task.py",18,"run","self.check()"],
    [".../modules/monitor/checks/collector.py",223,"wrapper","_check.run()"],
    [".../modules/monitor/checks/__init__.py",630,"run","self._roll_up_instance_metadata()"],
    [".../modules/monitor/checks/__init__.py",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",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,"run","super(RepeatTask, self).run()"],
    [".../modules/monitor/bot/task.py",18,"run","self.check()"],
    [".../modules/monitor/checks/collector.py",223,"wrapper","_check.run()"],
    [".../modules/monitor/checks/__init__.py",630,"run","self._roll_up_instance_metadata()"],
    [".../modules/monitor/checks/__init__.py",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()"]
  ],
...

重播

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

要完全防止和控制內存泄漏幾乎是不可能的,像rust這樣的安全編程語言也不能保證程序不會泄漏內存。

許多引起內存不安全的行爲,如數組訪問越界、訪問釋放後的內存等,均可以經過制定更嚴格的編程模型(如rust提出的全部權+生命週期規則)甚至數據競爭問題來避免。

然而,觸發內存泄漏的行爲,如競爭條件,須要開發人員將開發組件和業務規則結合起來。設想一個須要手動觸發刷新的數據隊列。結果,咱們在推送數據時忘記調用它。這種內存泄漏沒法經過任何常規檢查規則來識別。

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

總結

經過本節的學習,咱們瞭解了經過if else在不一樣條件下控制代碼流和執行不一樣代碼。for/while和如何定義函數有兩種不一樣的循環方法,包括函數的返回值和參數傳遞方法、position參數傳遞和向函數傳遞參數時的key=value參數傳遞。

相關文章
相關標籤/搜索