內存是 Unix/Linux 內核所管理的最為重要的資源之一,內存管理是系統管理中非常重要也是最復雜的的部分。系統管理員需要掌握內存管理的基本工作原理以及使用合適的工具與策略監控內存的工作狀態。 本文將分別闡述 AIX 和 Linux 系統中所涉及到的內存監控的方法,並對其中涉及到的內核內存管理的原理做初步的說明。
AIX 內存管理與監控
內存管理概述
內存管理在不同的操作系統中會有不同的實現。AIX 系統使用 VMM(Virtual Memory Manager) 實現物理內存的管理,處理應用程序的內存分配請求與內存回收。
內存和交換空間一般都是通過頁面來進行分配和管理,VMM 將所有的內存段劃分為若干個頁面,Power4 芯片支持 4K,64K,和 16M 大小的虛擬內存頁, Power5 芯片支持 4K,64K,16M,16G 大小的虛擬內存頁,每個頁面的缺省大小是 4KB。虛擬內存頁面越大,對需要大內存塊的應用程序可以起到優化作用,主要是提高 TLB 的命中率。
當我們執行應用程序的時候,內存中的頁面會被逐漸的占用,這裡我們設計兩個重要的參數: Minfree( 最小空閒頁面的大小 ) 和 Maxfree( 最大空閒頁面的大小 )。當空閒的內存達到 Minfree 大小的時候, VMM 的調頁算法將被喚醒,將內存中的頁面轉移到交換空間中, 知道空閒內存達到 Maxfree,才停止調頁。
上面主要是對 AIX 內存管理中所涉及到的的基本概念做了簡單的介紹說明,對於任何與內存相關的操作,了解這些概念都是非常必要的。
系統管理員在進行正確的優化或者問題發生之前,必須首先監視系統,使用合適的工具捕獲基准數據,並且知道如何進行分析工作。下面筆者將介紹 AIX 系統所提供的工具來監控系統內存的使用情況。
內存調整命令
與其他的子系統相比,內存調整更為困難,但同時收到的效果往往更加顯著,特別是在那些尚未對各種內存參數進行優化的運行環境中。系統管理員可以通過 vmo 命令動態的調整內存參數,進行內存性能優化方面的各種實踐。
vmo
Vmo 命令用來管理虛擬內存可調試的參數。例如如果我們發現空閒內存不足, 可以使用下面的命令增加 Minfree 和 Maxfree 參數:
# vmo – o minfree=1024 – o maxfree=30070 Setting maxfree to 30070 Setting minfree to 1024
注:-p 參數能夠使修改永久生效,而且立即生效,不需要重啟,下次重啟設置仍然有效。例如 vmo -p – o minfree=1024 命令能夠永久設置空閒的虛擬內存值為 1024
一般情況下,minfree 和 maxfree 的設定值可以通過下面的公式計算得到:
maxfree=minnum(memory/128,128)
minfree=maxfree/8
-a 參數能夠顯示當前所有的內存參數設置,之後系統管理員可以對其中的任何參數進行調整,在此必須說明的是:對內存參數的任何微小改動都有可能造成系統運行的不穩定,所以系統管理員做的任何修改,都必須非常慎重並且對可能造成的影響有所了解。 上文提到的兩個關鍵參數 minfree 和 maxfree 也包含於下面的列表中。
# vmo -a ams_loan_policy = n/a force_relalias_lite = 0 kernel_heap_psize = 65536 lgpg_regions = 0 lgpg_size = 0 low_ps_handling = 1 maxfree = 30070 maxperm = 902102 maxpin = 845450 maxpin% = 80 memory_frames = 1048576 memplace_data = 2 memplace_mapped_file = 2 memplace_shm_anonymous = 2 memplace_shm_named = 2 memplace_stack = 2 memplace_text = 2 memplace_unmapped_file = 2 minfree = 1024 minperm = 30070 minperm% = 3 nokilluid = 0 npskill = 1024 npswarn = 4096 numpsblks = 131072 pinnable_frames = 868968 relalias_percentage = 0 scrub = 0 v_pinshm = 0 vmm_default_pspa = 0 wlm_memlimit_nonpg = 1
# 這段代碼使用了 vmstat 命令得到系統內存狀態信息,並對結果進行逐行解析,得到各個字段的數據。 if ( $total_mem ) { $rate = $used_mem / $total_mem; } # 計算得到了當前全局內存使用率 if ( $rate > 0.75 ) { print "Warning: Memory is not enough\n"; } # 如果內存使用率大於 0.75, 將打印出警告信息。 if ( $rate > 0.9 ) { my $line_count = 0; my @output = `ps aux | head -1;ps aux | sort -rn +5`; foreach ( @output ) { if ( $line_count ) { my @killed_process = split /\s+/,$_; print "Warning: Out of memory. Kill process: @killed_process[1]\n"; # 發送警告信息給 root 用戶,保存程序運行記錄。 `echo "Process @killed_process[1] has been killed because of unlimited memory \ allocation" | mail -s "Out of memory" root` `kill -11 @killed_process[1]`; last; } $line_count = $line_count + 1; } # 如果內存使用率大於 0.9,腳本將調用 ps 命令並且找出內存使用率最高的進程,打印出將要殺掉進程的警告信息, #殺掉內存使用率最高的進程。 此過程將循環進行知道內存占用率低於 0.9 }
From [email protected] Tue July 31 13:01:12 2009 X-Original-To: root Delivered-To: [email protected] Date: Tue, 31 July 2009 13:01:11 -0400 To: [email protected] Subject: Out of memory User-Agent: Heirloom mailx 12.2 01/07/07 MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit From: [email protected] ------------------------------------------------------------ Process 10482 has been killed because of unlimited memory allocation
上面的腳本 MemMonitor.perl 實現了自動監控內存使用率,並對內存占用率比較高的時候分別作了處理,能夠保障內存子系統的穩定運行。 下面我們將借助系統的 cron 服務每間隔設定的一段時間自動調用上面的腳本,實現內存監控管理的完全自動化。
使用命令“crontab – e”編輯 crontab,添加一條自動運行腳本 MemMonitor.perl 的項目:
*/2 * * * * /tmp/MemMonitor.perl 2>&1 >> /tmp/memmonitor.log
此時 MemMonitor.per 將被每兩分鐘自動執行一次,並將輸出結果保存在 /tmp/memmonitor.log 中。
總結
本文詳細介紹了 Unix/Linux 上常用的內存管理與監控的命令,並通過編寫腳本實例應用內存管理的命令,實現了內存管理的自動化,當內存使用率過高的時候,給出警告信息,通過關閉內存占用率高的進程來確保了系統全局的穩定運行,並對其中所做的操作做了日志記錄,方便了系統管理員監測並調試系統內存故障。