如何「快準狠」找到系統記憶體的問題?

2022-09-09 13:42:26 字數 3627 閱讀 8961

為了分析記憶體的效能瓶頸,首先你要知道,怎樣衡量記憶體的效能,也就是效能指標問題。

首先,你最容易想到的是系統記憶體使用情況,比如已用記憶體剩餘記憶體共享記憶體可用記憶體快取緩衝區的用量等。

第二類很容易想到的,應該是程序記憶體使用情況,比如程序的虛擬記憶體常駐記憶體共享記憶體以及swap 記憶體等。

當然,這些指標中,常駐記憶體一般會換算成佔系統總記憶體的百分比,也就是程序的記憶體使用率。

除了這些很容易想到的指標外,我還想再強調一下,缺頁異常。

記憶體分配的原理中,我曾經講到過,系統呼叫記憶體分配請求後,並不會立刻為其分配物理記憶體,而是在請求首次訪問時,通過缺頁異常來分配。缺頁異常又分為下面兩種場景。

顯然,主缺頁異常公升高,就意味著需要磁碟 i/o,那麼記憶體訪問也會慢很多。

除了系統記憶體和程序記憶體,第三類重要指標就是 swap 的使用情況,比如 swap 的已用空間、剩餘空間、換入速度和換出速度等。

這些記憶體的效能指標都需要我們熟記並且會用,我把它們彙總成了乙個思維導圖,你可以儲存列印出來,或者自己仿照著總結乙份。

首先,你應該注意到了,所有的案例中都用到了 free。這是個最常用的記憶體工具,可以檢視系統的整體記憶體和 swap 使用情況。相對應的,你可以用 top 或 ps,檢視程序的記憶體使用情況。

然後,在快取和緩衝區的原理篇中,我們通過 proc 檔案系統,找到了記憶體指標的**;並通過 vmstat,動態觀察了記憶體的變化情況。與 free 相比,vmstat 除了可以動態檢視記憶體變化,還可以區分快取和緩衝區、swap 換入和換出的記憶體大小

接著,在快取和緩衝區的案例篇中,為了弄清楚快取的命中情況,我們又用了 cachestat ,檢視整個系統快取的讀寫命中情況,並用 cachetop 來觀察每個程序快取的讀寫命中情況。

再接著,在記憶體洩漏的案例中,我們用 vmstat,發現了記憶體使用在不斷增長,又用 memleak,確認發生了記憶體洩漏。通過 memleak 給出的記憶體分配棧,我們找到了記憶體洩漏的可疑位置。

最後,在 swap 的案例中,我們用 sar 發現了緩衝區和 swap 公升高的問題。通過 cachetop,我們找到了緩衝區公升高的根源;通過對比剩餘記憶體跟 /proc/zoneinfo 的記憶體閾,我們發現 swap 公升高是記憶體**導致的。案例最後,我們還通過 /proc 檔案系統,找出了 swap 所影響的程序。

最後,在 swap 的案例中,我們用 sar 發現了緩衝區和 swap 公升高的問題。通過 cachetop,我們找到了緩衝區公升高的根源;通過對比剩餘記憶體跟 /proc/zoneinfo 的記憶體閾,我們發現 swap 公升高是記憶體**導致的。案例最後,我們還通過 /proc 檔案系統,找出了 swap 所影響的程序。

到這裡,你是不是再次感覺到了來自效能世界的「惡意」。效能工具怎麼那麼多呀?其實,還是那句話,理解記憶體的工作原理,結合效能指標來記憶,拿下工具的使用方法並不難。

同 cpu 效能分析一樣,我的經驗是兩個不同維度出發,整理和記憶。

同樣的,根據記憶體效能指標和工具的對應關係,我做了兩個**,方便你梳理關係和理解記憶。當然,你也可以當成「指標工具」和「工具指標」指南來用,在需要時直接查詢。

第乙個**,從記憶體指標出發,列舉了哪些效能工具可以提供這些指標。這樣,在實際排查效能問題時,你就可以清楚知道,究竟要用什麼工具來輔助分析,提供你想要的指標。

第二個**,從效能工具出發,整理了這些常見工具能提供的記憶體指標。掌握了這個**,你可以最大化利用已有的工具,盡可能多地找到你要的指標。

這些工具的具體使用方法並不用背,你只要知道有哪些可用的工具,以及這些工具提供的基本指標。真正用到時, man 一下查它們的使用手冊就可以了。

我相信到這一步,你對記憶體的效能指標已經非常熟悉,也清楚每種效能指標分別能用什麼工具來獲取。

那是不是說,每次碰到記憶體效能問題,你都要把上面這些工具全跑一遍,然後再把所有記憶體效能指標全分析一遍呢?

自然不是。前面的 cpu 效能篇我們就說過,簡單查詢法,雖然是有用的,也很可能找到某些系統潛在瓶頸。但是這種方法的低效率和大工作量,讓我們首先拒絕了這種方法。

還是那句話,在實際生產環境中,我們希望的是,盡可能地定位系統瓶頸,然後盡可能地優化效能,也就是要又快又準地解決效能問題。

那有沒有什麼方法,可以又快又準地分析出系統的記憶體問題呢?

舉個最簡單的例子,當你看到系統的剩餘記憶體很低時,是不是就說明,程序一定不能申請分配新記憶體了呢?當然不是,因為程序可以使用的記憶體,除了剩餘記憶體,還包括了可**的快取和緩衝區。

所以,為了迅速定位記憶體問題,我通常會先執行幾個覆蓋面比較大的效能工具,比如 free、top、vmstat、pidstat 等。

具體的分析思路主要有這幾步。

先用 free 和 top,檢視系統整體的記憶體使用情況。

再用 vmstat 和 pidstat,檢視一段時間的趨勢,從而判斷出記憶體問題的型別。

最後進行詳細分析,比如記憶體分配分析、快取 / 緩衝區分析、具體程序的記憶體使用分析等。

同時,我也把這個分析過程畫成了一張流程圖,你可以儲存並列印出來使用。

圖中列出了最常用的幾個記憶體工具,和相關的分析流程。其中,箭頭表示分析的方向,舉幾個例子你可能會更容易理解。

第乙個例子,當你通過 free,發現大部分記憶體都被快取占用後,可以使用 vmstat 或者 sar 觀察一下快取的變化趨勢,確認快取的使用是否還在繼續增大。

如果繼續增大,則說明導致快取公升高的程序還在執行,那你就能用快取 / 緩衝區分析工具(比如 cachetop、slabtop 等),分析這些快取到底被**占用。

第二個例子,當你 free 一下,發現系統可用記憶體不足時,首先要確認記憶體是否被快取 / 緩衝區占用。排除快取 / 緩衝區後,你可以繼續用 pidstat 或者 top,定位占用記憶體最多的程序。

找出程序後,再通過程序記憶體空間工具(比如 pmap),分析程序位址空間中記憶體的使用情況就可以了。

第三個例子,當你通過 vmstat 或者 sar 發現內存在不斷增長後,可以分析中是否存在記憶體洩漏的問題。

比如你可以使用記憶體分配分析工具 memleak ,檢查是否存在記憶體洩漏。如果存在記憶體洩漏問題,memleak 會為你輸出記憶體洩漏的程序以及呼叫堆疊。

注意,這個圖里我沒有列出所有效能工具,只給出了最核心的幾個。這麼做,一方面,確實不想讓大量的工具列表嚇到你。

另一方面,希望你能把重心先放在核心工具上,通過我提供的案例和真實環境的實踐,掌握使用方法和分析思路。 畢竟熟練掌握它們,你就可以解決大多數的記憶體問題。

作業系統 具有快表的記憶體轉換機構

基本位址轉換機構 一組硬體機構,將邏輯位址轉換成實體地址,需要兩次訪存,先查頁表再查記憶體 具有快表的位址轉換機構 1 區域性性原理 2 什麼是快表 3 引入快表後,位址轉換只需要一次訪存 區域性性原理 時間區域性性 程式中執行了某條指令,不久後這條指令可能會再次執行 訪問了某個變數,不久後可能會再...

作業系統的記憶體分配問題

記憶體即我們平時說的電腦記憶體 4g 8g等 非硬碟容量,那是外存。記憶體是存放cpu運算資料的地方。這裡就得扯到裝系統的乙個十分常見問題了,即系統是安裝32位的還是64位的。根據以往裝系統的經驗,4g以下通常是安裝32位的作業系統,以上就安裝64位的。但這是為什麼?下面給出我最近自己的理解。因為作...

如何除錯Python 程式的記憶體洩露問題

如果大家在 linux 或者 macos 下面執行一段可能導致記憶體洩露的程式,那麼你可能會看到下面這樣的情況 而如果你用的系統是 windows,那麼可能電腦直接就卡死了。但是,除錯這種 oom out of memory 的問題有時候是非常困難的,因為你不知道 哪個地方會導致記憶體洩露。但是如果...