Linux性能優化之內存優化(二)


前言

  不知道大家看完前面一章關於CPU優化,是否受到相應的啟發呢?如果遇到任何問題,可以留言和一起探討這方面的問題。接下來我們介紹一些關於內存方面的知識。內存管理軟件包括虛擬內存系統、地址轉換、交換、換頁和分配。與性能密切相關的內容包括:內存釋放、空閑鏈表、頁掃描、交換、進程地址空間和內存分配器。在Linux中,空閑鏈表通常由分配器消耗,如內核的slab分配器和SLUB,以及用戶級分配器(glibc,linux系統)libmalloc、libumem和mtmalloc。

  • slab: 內核slab分配器管理特定大小的對象緩存,使他們能夠被快速的回收利用,並且避免頁分配的開銷。適用於處理固定大小結構的內核內存分配。
  • slub: 基於slab分配器。它主要是解決slab分配器帶來的問題,其中包括移除對象隊列,以及每個CPU緩存,把NUMA優化留給頁分配器。
  • glibc: 結合多種非配器策略的高效分配器,它基於分配請求的長度進行分配。較小的分配來自內存集合,包括用伙伴關系算法合並長度相近的單位。較大的分配用樹高效地搜索空間。對於非常大的分配,會轉到mmap()。

  回收大多是從內核的slab分配器緩存釋放內存。這些緩存包含slab大小的未使用內存塊,以供充裕。內核頁面換出守護進程管理利用換頁釋放內存。當主存中可用的空閑鏈表低於閾值時,頁面換出守護進程會開始頁掃描。頁面換出守護進程被稱作kswapd(),它掃描非活動和活動內存的LRU頁列表以釋放頁面。它的激活基於空閑內存核兩個提供滯后的閾值。一旦空閑內存達到最低閾值,kswapd運行於同步模式,按需求釋放內存頁。該最低閾值是可調的(vm.min_free_kbytes),並且其他閾值基於它按比例放大。

相關概念

  • 主存:物理內存,描述了計算機的告訴數據存儲區域,通常是動態隨機訪問內存;
  • 虛擬內存: 抽象的主從概念,它幾乎是無限的和非競爭性的;
  • 常駐內存:當前處於主存中的內存;
  • 匿名內存:無文件系統位置或者路徑名的內存。它包括進程地址空間的工作數據,稱作堆;
  • 地址空間:內存上下文。每個進程和內核都有對應的虛擬地址空間;
  • 頁:操作系統和CPU使用的內存單位。它一直以來是4KB和8KB。現代的處理器允許多種頁大小以支持更大的頁面尺寸,以及更大的透明大頁;
  • 缺頁:無效的內存訪問;
  • 換頁:在主存與存儲設備間交換頁;
  • 交換:指頁面從主從轉移到交換設備(遷移交換頁);
  • 交換(空間):存放換頁的匿名數據和交換進程的磁盤空間;

  進程地址空間是一段范圍的虛擬頁,由硬件和軟件同事管理,按需映射到物理頁。這些地址被划分為段以存放線程棧、進程可執行、庫和堆。應用程序可執行段包括分離的文本和數據段。庫也由分離的可執行文本和數據段組成。分別如下:

  • 可執行文本:包括可執行的進程CPU指令。由文件系統中的二進制應用程序文本映射而來。它是只讀的並帶有執行的權限。
  • 可執行數據:包括已初始化的變量,由二進制應用程序的數據段映射而來。有讀寫權限,因此這些變量在應用程序的運行過程中可以被修改。
  • 堆:應用程序的臨時工作內存並且是匿名內存。它按需增長並且用mollac()分配。
  • 棧:運行中的線程棧,映射為讀寫。

  對於內存而言,經常關注的信息如下:

  • 頁掃描:尋找連續的頁掃描(超過10秒),它是內存壓力的預兆。可以使用sar -B並查看pgscan列。
  • 換頁:換頁是系統內存低的進一步征兆。可以使用vmstat 並查看si(換入) 和 so(換出)列。
  • 可用內存:查看和關注buffer和cache值;
  • OOM終結者:在系統日志/var/log/messages或者dmesg中查看,直接搜索"Out of memory";
  • top/prstat:查看那些進程和用戶是常駐物理內存和虛擬內存的最大使用者;
  • stap/perf:內存分配的棧跟蹤,確認內存使用的原因;

  如何快速定位內存故障?
  1. 首先應該檢查飽和度(作為釋放內存壓力的衡量,頁掃描、換頁、交換和Linux OOM終結者犧牲進度的使用程度),因為持續飽和狀態是內存問題的征兆。這些指標可以通過vmstat、sar、dmesg等操作系統工具輕易獲得。對於配置了獨立磁盤交換設備的系統,任何交換設備活動都是內存壓力的征兆。

  2. 使用率(使用內存和可用內存,物理內存和虛擬內存都應該關注)通常較難讀取和解讀。比如一個系統可能會報告只有幾十兆內存可用,但事實上它有10GB的文件系統緩存在,需要時立刻被應用程序回收利用。虛擬內存使用,這應該也是我們關注的一個點。

  3. 內存錯誤(Out of memory)一般都是由應用程序報告。

關於內存性能排查命令

vmstat

[root@zbredis-30104 ~]# vmstat 
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu-----
r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
0  0    0 14834208 158384 936512    0    0     0     0    1    3  0  0 100  0  0

提示:

  swpd:交換處的內存量;
  free:空閑的可用內存;
  buff: 用戶緩沖緩存的內存;
  cache: 用於頁緩存的內存;
  si: 換入的內存(換頁);
  so:換出的內存(換頁);

如果si 和 so列一直非0,那么系統正存在內存壓力並換頁到交換設備或文件。經常使用參數為"vmstat 1 -Sm"和"vmstat -a 1";

sar

  -B: 換頁統計信息;

  -H: 大頁面統計信息
  -r: 內存使用率
  -R:內存統計信息
  -S:交換空間統計信息
  -W:交換統計信息

slabtop

  通過slab分配器實時輸出內核slab緩存使用情況;

[root@localhost ~]# slabtop -sc

Active / Total Objects (% used)    : 297064 / 300262 (98.9%)
Active / Total Slabs (% used)      : 6638 / 6638 (100.0%)
Active / Total Caches (% used)     : 66 / 96 (68.8%)
Active / Total Size (% used)       : 80612.41K / 81749.09K (98.6%)
Minimum / Average / Maximum Object : 0.01K / 0.27K / 8.00K

OBJS ACTIVE  USE OBJ SIZE  SLABS OBJ/SLAB CACHE SIZE NAME                   
7648   7528  98%    2.00K    478	 16     15296K kmalloc-2048
65142  65142 100%    0.19K   1551	 42     12408K dentry
17985  17985 100%    0.58K    327	 55     10464K inode_cache
7110   7110 100%    1.06K    237	 30	 7584K xfs_inode
10880  10160  93%    0.50K    170	 64	 5440K kmalloc-512
30564  30564 100%    0.11K    849	 36	 3396K sysfs_dir_cache

輸出包括頂部的匯總和slab列表。其中包括對象數量(OBJS)、多少是活動的(ACTIVE)、使用百分比(USE)、對象大小(OBJ SIZE,字節)和緩存大小(CACHE SIZE,字節)。

ps

  可以列出包括內存使用統計信息在內的所有進程細節;

  %MEM: 主存使用(物理內存、RSS)占總內存的百分比;
  RSS:常駐集合大小;
  VSZ: 虛擬內存大小;

提示:RSS顯示主存使用,它也包括如系統庫在內的映射共享段,可能會被幾十個進程共享。如果你把RSS列求和,會發現她超過系統內存總和,這是由於重復計算了這部分共享內存。

pmap

[root@localhost ~]# pmap -x 1096
1096:   /usr/sbin/mysqld --basedir=/usr --datadir=/var/lib/mysql --plugin-dir=/usr/lib64/mysql/plugin --log-error=/var/log/mysqld.log --pid-file=/var/run/mysqld/mysqld.pid --socket=/var/lib/mysql/mysql.sock
Address           Kbytes     RSS   Dirty Mode  Mapping
0000000000400000   11960    3468       0 r-x-- mysqld
00000000011ae000     668     240     172 r---- mysqld
0000000001255000    1028     364     208 rw--- mysqld
0000000001356000     340     312     312 rw---   [ anon ]
0000000001887000    7508    7344    7344 rw---   [ anon ]
...省略部分...
00007ffc659e9000     132      72      72 rw---   [ stack ]
00007ffc65ba1000       8       4       0 r-x--   [ anon ]
ffffffffff600000       4       0       0 r-x--   [ anon ]
---------------- ------- ------- ------- 
total kB          961172  121756  116468

內存優化

首先關於內核優化的相關參數

vm.dirty_background_bytes:默認值為0, 觸發pdflush后台回寫的臟存儲器量;

vm.dirty_background_ratio:默認值10, 觸發pdflush后台回寫臟系統存儲器百分比;
vm.dirty_bytes:默認值為0,觸發一個寫入進程開始回寫的臟存儲器量;
vm.dirty_ratio:默認值為20,觸發一個寫入進程開始回寫的臟系統存儲器比例;
vm.dirty_expire_centisecs:默認值為3000,使用pdflush的臟存儲器最小時間;
vm.dirty_writeback_centisecs:默認值為500,pdflush活躍時間間隔(0為停用);
vm.min_free_kbytes:默認值為 dynamic,設置期望的空閑存儲器量(一些內核自動分配器能消耗它);
vm.overconmmit_memory:默認值為0,0表示利用探索法允許合理的國度分配;1表示一直國度分配;3表示禁止國度分配;
vm.swappiness:默認值為60,相對於頁面高速緩存回收更傾向用交換釋放存儲器的程度;
vm.vfs_cache_pressure:默認值為100,表示回收高速緩存的目錄和inode對象的程度。較低的值會保留更多;0意味着從不回收,容器導致存儲器耗盡的情況;

提示:

vm.dirty_background_bytes和vm.dirty_background_ratio是互斥的,dirty_bytes 和 dirty_ratio 也是如此,僅能設置一個。vm.swappiness參數對性能會產生顯著的影響,建議設置為0;因為應用程序內存能盡可能就地駐留。

       最后說明,在現在內核發展過程之中,linux內存頁面已經支持大頁面和超大頁面以及透明大頁面等,可以根據自身環境進行適當的調整。紅帽企業版 Linux 6 采用第二種方法,即使用超大頁面。簡單說,超大頁面是 2MB 和 1GB 大小的內存塊。2MB 使用的頁表可管理多 GB 內存,而 1GB 頁是 TB 內存的最佳選擇。

       超大頁面必須在引導時分配。它們也很難手動管理,且經常需要更改代碼以便可以有效使用。因此紅帽企業版 Linux 也部署了 透明超大頁面 (THP)。THP 是一個提取層,可自動創建、管理和使用超大頁面的大多數方面。
THP 系統管理員和開發者減少了很多使用超大頁面的復雜性。因為 THP 的目的是改進性能,所以其開發者(社區和紅帽開發者)已在各種系統、配置、程序和負載中測試並優化了 THP。這樣可讓 THP 的默認設置改進大多數系統配置性能。
  注:THP 目前只能映射異步內存區域,比如堆和棧空間。關於THP相關使用及問題可自行查閱資料。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM