記憶體使用過高點檢checklist

yuzhenjin 發表於 2020-11-22

正在執行的程式按照記憶體段來組織,記憶體段的型別有如下幾種:

  • 程式碼段:使用者程式指令,長期存在記憶體中

  • 資料段:全域性變數等,長期存在記憶體中

  • 堆:區域性變數,引數引數等,短期存在記憶體中

  • 棧:動態儲存,可變

程式碼段

  • 問題1:是否存在無用程式碼片段(函式,變數),無用全域性變數,無用的類私有變數等

    • 點檢手段: 通過靜態檢測工具來分析,或者人工grep的方法

    • 改進手段:直接刪除

  • 問題2:是否存在大量的程式碼片段巨集

    • 點檢手段:IDE,分析原始檔

    • 改進手段:用函式來代替巨集

  • 問題3:是否存在大量重複程式碼

    • 點檢手段:通過靜態檢測工具檢視原始碼重複之處

    • 改進手段:提取共同函式來消除重複

資料段

  • 問題1:是否存在建立非必要臨時檔案的情況

    • 點檢手段:通過命令du -sh /tmp/* 來檢視,是否存在一些無用的檔案是本程式建立的。

    • 改進手段:刪除無用的檔案

  • 問題2:程式是否直接使用大量RAW data

    • 點檢手段:檢視原始碼

    • 改進手段:使用壓縮過後的資料

  • 問題3:全域性變數作用域是否可以減少(尤其是隻在某一處或者幾處地方使用而已)

    • 點檢手段:靜態檢測工具

    • 改進手段:優化程式邏輯,全域性變數變區域性變數

  • 問題4:是否存在不合理的資料結構(尤其是size很大的全域性變數)

    • 點檢手段:分析原始碼

    • 改進手段:優化資料結構

  • 問題5:是否存在不合理的預留,尤其是專案初期由於資訊缺少,資料結構存在預留空間/欄位。

    • 點檢手段:分析原始碼中非0,1的魔法數字

    • 改進手段:優化資料結果(消除預留空間/欄位)

棧段

  • 問題1:是否存在函式遞迴呼叫的使用場景

    • 點檢手段:通過靜態檢測工具來分析,或者開發自己應該很清楚

    • 改進手段:優化程式結構,消除函式遞迴

  • 問題2:是否存在大的區域性變數

    • 點檢手段:grep原始碼:grep -nr "[",搜尋使用陣列下標的地方,然後一一排查,發現比較大的陣列(比如100K以上)就要引起注意了。

    • 改進手段:如果確實必須的,將大區域性變數宣告為全域性,然後按照引用傳遞給函式

  • 問題3:是否存在函式引數較多的函式(比如超過了6個)

    • 點檢手段:靜態檢測工具

    • 改進手段:函式入參合並

  • 問題4:函式入參是否存在複製的問題

    • 點檢手段:grep原始碼

    • 改進手段:引用而不是值來傳遞引數

堆段

  • 問題1:是否存在記憶體洩漏

    • 點檢手段:通過指令碼定時監控程式記憶體使用情況;通過工具點檢

    • 改進手段:智慧指標代替裸指標, ...

  • 問題2:是否存在檔案控制程式碼增加或者程式使用檔案控制程式碼太多(和設計不符)

    • 點檢手段:檢視使用者級最大檔案描述限制:ulimit -n; 通過檢視 /proc/pid/fd,檢視程式佔有檔案控制程式碼數是否存在增加的情況;通過靜態檢測工具檢視是否存在檔案資源洩漏的情況

    • 改進手段:消除檔案資源洩漏

  • 問題3:STL中Vector容器記憶體未釋放(vector跟其它容器不同,即使呼叫了clear()函式,記憶體依然不會釋放,除非呼叫swap()函式/shrink_to_fit()函式)

    • 點檢手段:grep原始碼

    • 改進手段:使用其它的STL容器替代Vector,或者呼叫clear函式後還需要呼叫swap函式等

系統

  • 問題1:程式的執行緒數是否動態增加或者執行緒數和設計不符合

    • 點檢手段:ps -T -p <pid>或者top -H

    • 改進手段:優化執行緒動態參見部分邏輯

  • 問題2:是否存在週期性呼叫系統shell指令的情況

    • 點檢手段:grep -nr system; grep -nr popen

    • 改進手段:採用系統API代替shell指令碼

  • 問題3:makefile存在不合理,連結了不使用的動態庫或者靜態庫

    • 點檢手段:分析makefile

    • 改進手段:優化makefile,連結時去掉非必要的動態庫

  • 問題4:makefile中存在優先使用靜態庫代替動態庫的情況

    • 點檢手段:分析makefile

    • 改進手段:優化makefile,優先使用動態庫