Linux System and Performance Monitoring(Memory篇) 5.0 Virtual Memory介紹 虛擬內存就是採用硬盤對物理內存進行擴展,所以對可用內存的增加是要相對在一個有效範圍內的.內核會寫當前未使用內存塊的內容到硬盤上,此時這部分內存被用於其它用途.當再一次需要原始內容時,此時再讀回到內存中.這對於用戶來說,是完全透明的;在Linux 下運行的程式能夠看到,也僅僅是大量的可用內存,同時也不會留意到,偶爾還有部分是駐留在磁盤上的.當然,在硬盤上進行讀和寫,都是很慢的(大約會慢上千倍),相對於使用真實內存的話,因此程式無法運行的更快.用硬盤的一部分作為Virtual Memory,這就被稱為"swap space"(譯註:交換空間). 5.1 Virtual Memory Pages 虛擬內存被分為很多 pages(譯註:頁),在X86架構中,每個虛擬內存頁為 4KB.當內核寫內存到磁盤或者讀磁盤到內存,這就是一次寫內存到頁的過程.內核通常是在swap 分區和文件系統之間進行這樣的操作. 5.2 Kernel Memory Paging 內存分頁在正常情況下總是活躍的,與memory swapping(譯註:內存交換)之間不要搞錯了.內存分頁是指內核會定期將內存中的數據同步到硬盤,這個過程就是Memory Paging.日復一日,應用最終將會消耗掉所有的內存空間.考慮到這點,內核就必須經常掃描內存空間並且收回其中未被使用的內存頁,然後再重新分配內存空間給其他應用使用. 5.3 The Page Frame Reclaim Algorithm(PFRA)(譯註:頁框回收演算法) PFRA 就是OS 內核用來回收並釋放內存空間的演算法.PFRA 選擇哪個內存頁被釋放是基於內存頁類型的.頁類型有以下幾種: Unreclaimable –鎖定的,內核保留的頁面 Swappable –匿名的內存頁 Syncable –通過硬盤文件備份的內存頁 Discardable –靜態頁和被丟棄的頁 除了第一種(Unreclaimable)之外其餘的都可以被PFRA進行回收. 與PFRA 相關的,還包括kswapd 內核線程以及Low On Memory Reclaiming(LMR演算法) 這2種進程和實現. 5.4 kswapd kswapd 進程負責確保內存空間總是在被釋放中.它監控內核中的pages_high和pages_low閥值.如果空閑內存的數值低於 pages_low,則每次 kswapd 進程啟動掃描並嘗試釋放32個free pages.並一直重復這個過程,直到空閑內存的數值高於 pages_high. kswapd 進程完成以下幾個操作: 1,如果該頁處於未修改狀態,則將該頁放置回空閑列表中. 2,如果該頁處於已修改狀態並可備份迴文件系統,則將頁內容寫入到磁盤. 3,如果該頁處於已修改狀態但沒有任何磁盤備份,則將頁內容寫入到swap device. # ps -ef | grep kswapd root 30 1 0 23:01 ? 00:00:00 [kswapd0] 5.5 Kernel Paging with pdflush pdflush 進程負責將內存中的內容和文件系統進行同步操作.也就是說,當一個文件在內存中進行修改後, pdflush 將負責寫回到磁盤上. # ps -ef | grep pdflush root 28 3 0 23:01 ? 00:00:00 [pdflush] root 29 3 0 23:01 ? 00:00:00 [pdflush] 當內存中存在10% 的臟頁,pdflush 將被啟動同步臟頁迴文件系統里.這個參數值可以通過 vm.dirty_background_ratio 來進行調整. (譯註: Q:什麼是臟頁? A:由於內存中頁緩存的緩存作用,寫操作實際上都是延遲的.當頁緩存中的數據比磁盤存儲的數據還要更新時,那麼該數據就被稱做臟頁.) # sysctl -n vm.dirty_background_ratio 10 在多數環境下,Pdflush與PFRA是獨立運行的,當內核調用LMR時,LMR 就觸發pdflush將臟頁寫入到磁盤里. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 在2.4 內核下,一個高負荷的內存環境中,系統將遇到交換過程中不斷的崩潰.這是因為PFRA 從一個運行進程中,偷取其中一個內存頁並嘗試使用.導致結果就是,這個進程如果要回收那個頁時,要是沒有就會嘗試再去偷取這個頁,這樣一來,就越來越糟糕了.在2.6 內核下,使用"Swap token"修復了這個BUG,用來防止PFRA 不斷從一個進程獲取同一個頁. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 5.6 案例學習:大量的入口I/O vmstat 工具報告里除了CPU 使用情況,還包括了虛擬內存.以下就是vmstat 輸出中關於虛擬內存的部分: Table 2: The vmstat Memory Statistics Field Description Swapd The amount of virtual memory in KB currently in use. As free memory reaches low thresholds, more data is paged to the swap device. 當前虛擬內存使用的總額(單位:KB).空閑內存達到最低的閥值時,更多的數據被轉換成頁到交換設備中. Free The amount of physical RAM in kilobytes currently available to running applications. 當前內存中可用空間位元組數. Buff The amount of physical memory in kilobytes in the buffer cache as a result of read() and write() operations. 當前內存中用於read()和write()操作的緩沖區中緩存位元組數 Cache The amount of physical memory in kilobytes mapped into process address space. 當前內存中映射到進程地址空間位元組數 So The amount of data in kilobytes written to the swap disk. 寫入交換空間的位元組數總額 Si The amount of data in kilobytes written from the swap disk back into RAM. 從交換空間寫回內存的位元組數總額 Bo The amount of disk blocks paged out from the RAM to the filesystem or swap device. 磁盤塊頁面從內存到文件或交換設備的總額 Bi The amount of disk blocks paged into RAM from the filesystem or swap device. 磁盤塊頁面從文件或交換設備到內存的總額 以下 vmstat 的輸出結果,就是演示一個在I/O 應用中,虛擬內存在高負荷情況下的環境 # vmstat 3 procs memory swap io system cpu r b swpd free buff cache si so bi bo in cs us sy id wa 3 2 809192 261556 79760 886880 416 0 8244 751 426 863 17 3 6 75 0 3 809188 194916 79820 952900 307 0 21745 1005 1189 2590 34 6 12 48 0 3 809188 162212 79840 988920 95 0 12107 0 1801 2633 2 2 3 94 1 3 809268 88756 79924 1061424 260 28 18377 113 1142 1694 3 5 3 88 1 2 826284 17608 71240 1144180 100 6140 25839 16380 1528 1179 19 9 12 61 2 1 854780 17688 34140 1208980 1 9535 25557 30967 1764 2238 43 13 16 28 0 8 867528 17588 32332 1226392 31 4384 16524 27808 1490 1634 41 10 7 43 4 2 877372 17596 32372 1227532 213 3281 10912 3337 678 932 33 7 3 57 1 2 885980 17800 32408 1239160 204 2892 12347 12681 1033 982 40 12 2 46 5 2 900472 17980 32440 1253884 24 4851 17521 4856 934 1730 48 12 13 26 1 1 904404 17620 32492 1258928 15 1316 7647 15804 919 978 49 9 17 25 4 1 911192 17944 32540 1266724 37 2263 12907 3547 834 1421 47 14 20 20 1 1 919292 17876 31824 1275832 1 2745 16327 2747 617 1421 52 11 23 14 5 0 925216 17812 25008 1289320 12 1975 12760 3181 772 1254 50 10 21 19 0 5 932860 17736 21760 1300280 8 2556 15469 3873 825 1258 49 13 24 15 根據觀察值,我們可以得到以下結論: 1,大量的disk pages(bi)被寫入內存,很明顯在進程地址空間里,數據緩存(cache)也在不斷的增長. 2,在這個時間點上,空閑內存(free) 始終保持在17MB,即使數據從硬盤讀入而在消耗RAM. 3,為了維護空閑列表, kswapd 從讀/寫緩存區(buff)中獲取內存並分配到空閑列表裡.很明顯可以看到buffer cache(buff) 在逐漸的減少中. 4, 同時kswapd 進程不斷的寫臟頁到swap device(so)時,很明顯虛擬內存的利用率是在逐漸的增加中(swpd). 5.7 結論 監控虛擬內存性能由以下幾個部分組成: 1,當系統中出現較少的頁錯誤,獲得最好的響應時間,是因為memory caches(譯註:內存高速緩存)比disk caches更快(譯註:磁盤高速緩存). 2,較少的空閑內存,是件好事情,那意味著緩存的使用更有效率.除非在不斷的寫入swap device和disk. 3,如果系統不斷報告,swap device總是繁忙中,那就意味著內存已經不足,需要升級了.