Hugemem Kernel Explained [轉]
這篇文章幾個月前就讀過,現在忘得也七七八八了。當時讀的時候是純粹的研究下,現在再讀是因為有實際需求裡面涉及到這個,雖然已經更改用了4G/4G。感覺這次讀起來更有感觸。 文章中所說的發生 out of memory ,也就是我這兒之前改成hugemem核心的原因。修改完之後,確實穩定下來了。 至於為什麼會out of memory(畢竟記憶體不大,4G,REDHAT AS3U6,ORACLE 9206 rac ,OCFS),猜測下的話,資料庫前端連線很多,smp的記憶體管理更容易耗盡低端記憶體。然後系統隨機殺程式,crash掉。 |
紅旗DC系列Linux作業系統(x86平臺)中帶有四類核心:
- UP (支援單核心)
- SMP (支援多核心)
- hugemem
- Icc* (用intel C編譯器編譯的核心)
其中hugemem核心往往引起很多困惑,這裡希望能一勞永逸地把hugemem解釋清楚。
Hugemem vs. SMP
x86平臺下, 紅旗DC4.1和5.0所帶的smp和hugemem核心都開啟了PAE支援,也就是說都可以支援4G以上的實體記憶體。引入hugememe核心的目的_不是_支援超過4G實體記憶體(SMP核心就可以支援了),而是更穩定地支援大記憶體x86系統(所謂大記憶體可以簡單理解為超過12G記憶體的系統)。
smp和hugemem核心的 _唯一_區別是hugemem核心中打入了4G/4G補丁,使用4G/4G補丁可以將直接對映的核心資料程式碼地址空間從1G擴大到4G,將程式的虛擬地址空間也由3G擴大到4G。當實體記憶體過多時,管理這些實體記憶體的工作本身會佔用不少寶貴的核心地址空間(所謂低端記憶體),此時雖然總的實體記憶體還有不少空閒,由於低端記憶體耗盡,也可能會導致記憶體緊張,觸發OOM (Out of memory) killer,導致應用終止甚至核心崩潰。
如果超過12G實體記憶體,一般建議使用hugemem核心。不過,hugemem會帶來一定的效能損失。
以上說明對於一般使用者應該足夠了,如果想了解4G/4G補丁的更多細節,請繼續往下看...
大記憶體x86系統帶來的問題
4G/4G補丁主要應用於大記憶體x86系統(所謂大記憶體可以簡單理解為超過12G記憶體的系統),這樣的系統往往需要更多的核心地址空間和使用者地址空間。
在x86架構下,我們知道虛擬地址空間的大小為4G。在這4G空間中,使用者空間佔3G (0x00000000到0xbfffffff),核心空間佔1G(0xc0000000到0xffffffff)。這樣的分配策略成為3G/1G分配。這種分配方式對於擁有1G實體記憶體以下的系統是沒有任何問題的,即使超過1G實體記憶體,3G/1G分配策略也沒有什麼問題,因為核心可以在高階記憶體區域 (實體地址1G以上的記憶體)中存放一些核心資料結構(比如頁緩衝等)。然而,隨著實體記憶體的增多,3G/1G分配策略的問題也逐漸會暴露出來。這是因為一些關鍵的核心資料結構(比如用於管理實體記憶體的mem_map[])是存放在1G核心空間之內的。對於32G記憶體的系統,mem_map[]會佔用近 0.5G的低端記憶體(實體地址896M以下的記憶體),這樣留給核心其他部分的記憶體就不到所有記憶體的1.5%;而對於64G記憶體的系統,mem_map[] 本身就會耗盡所有的低端記憶體,造成系統無法啟動。把mem_map[]放到高階記憶體的做法也不太實際,因為mem_map[]和記憶體管理,體系結構相關底層實現,檔案系統以及驅動等幾乎所有的核心的關鍵部分均有聯絡。
4G/4G的作用
與3G/1G不同,4G/4G分配方式可以使核心空間由1G增加到4G,而使用者空間也由3G增加到4G。從 /proc/PID/maps 檔案中可以直觀地看到4G/4G所起的作用:
00e80000-00faf000 r-xp 00000000 03:01 175909 /lib/tls/libc-2.3.2.so
00faf000-00fb2000 rw-p 0012f000 03:01 175909 /lib/tls/libc-2.3.2.so
[...]
feffe000-ff000000 rwxp fffff000 00:00 0
從上面的maps可以看出,堆疊的棧底地址為0xff000000 (4GB 減去 16MB)。
從/proc/maps中則可以看到核心擁有了4G大小的低端記憶體,即使對於64G實體記憶體的系統,也有3.1G低端記憶體可供使用:
MemFree: 65958260 kB
HighTotal: 62914556 kB
HighFree: 62853140 kB
LowTotal: 3137464 kB
LowFree: 3105120 kB
相比3G/1G分配策略,對於4G實體記憶體系統,使用4G/4G分配可以增加低端記憶體達3倍以上,而對於32G實體記憶體系統,則會有更多的提升,達到原來的6倍。 理論上,4G/4G策略可以支援實體記憶體達200G的x86系統(如果硬體沒有限制的話),即使對於這樣的系統,4G/4G策略也能保證留有1G可用的低端記憶體。
4G/4G的代價
天下沒有免費的午餐,4G/4G也是如此。4G/4G透過完全分離使用者空間和核心空間的地址對映來增加低端記憶體,這樣做會帶來一些效能損失,具體而言,當發生上下文切換的時候(比如程式呼叫系統呼叫或者發生中斷),必須重新裝載頁表(3G/1G策略下不需要載入,因為核心可以直接“借用”每個程式的頁表進行記憶體對映),頁表的重新裝載後必須清空TLB(否則的話TLB中記錄的對映就和新的頁表不一致了),而清空TLB是一個很費時的操作,原先快取於TLB中的“舊”的對映會被丟掉,這一損失到還在其次(因為不經TLB直接從CPU快取中讀取頁表也並不會有太大延遲),最大的損失在於清空TLB(透過操作%cr3)這個操作本身代價很高。
何時使用(or不使用)4G/4G?
對於這個問題,沒有放之四海而皆準的答案。只有一些拇指定律。一般情況下,超過16G記憶體幾乎肯定需要使用4G/4G (除非執行的應用負載很輕,不過大記憶體系統很少有負載輕的情況),如果負載很重(不如執行資料庫進行著大量I/O操作),那麼12G以上的系統就應考慮使用4G/4G。也可以透過觀察空閒低端記憶體大小來大體判斷一下(/proc/meminfo),如果空閒低端記憶體(LowFree)小於100M,那麼就可以考慮使用4G/4G了。8G以下的系統一般不必使用4G/4G。
需要指出的是,如果需要大記憶體,最好的解決方法是用64位系統,而不是使用4G/4G。
Hugemem vs. SMP (revisited)
現在再來看hugemem是否感覺不一樣了?
x86平臺下, 紅旗DC4.1和5.0所帶的smp和hugemem核心都開啟了PAE支援,也就是說都可以支援4G以上的實體記憶體。引入hugememe核心的目的_不是_支援超過4G實體記憶體(SMP核心就可以支援了),而是更穩定地支援大記憶體x86系統(所謂大記憶體可以簡單理解為超過12G記憶體的系統)。
smp和hugemem核心的 _唯一_區別是hugemem 核心中打入了4G/4G補丁,這樣,可以直接對映的核心資料程式碼地址空間從1G擴大到4G,程式的的虛擬地址空間也由3G擴大到 4G。當實體記憶體過多時,管理這些記憶體本身會佔用不少寶貴的核心地址空間(所謂低端記憶體),此時雖然實體記憶體還夠用,由於低端記憶體耗盡,也可能會導致記憶體緊張,觸發OOM (Out of memory) killer,導致系統不穩定。
如果超過12G實體記憶體,一般建議使用hugemem核心。不過,hugemem會帶來一定的效能損失。
作為讀了以上這許多細節的bonus,其實hugemem和SMP還有一點區別:hugemem核心中有更多的所謂"unsupported"驅動 (DC4.1下的hugemem中所不支援的驅動要比SMP多出102個),這些驅動(比如qla1280)雖然(理論上)可以工作,但並沒有在 hugemem核心下進行過驗證,所以被打入到"unsupported"一族,言外之意是如果用這些驅動如果出了問題,紅旗(理論上)是不予支援的。可以透過安裝unsupported核心驅動包進行驅動。
參考資料:
- Patch: 4G/4G split on x86, 64 GB RAM (and more) support
- Linux Kernel 2.6 Features in Red Hat Enterprise Linux
原文見:
作者:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/23650854/viewspace-697938/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- [轉]Hugemem Kernel ExplainedAI
- Hugemem Kernel ExplainedAI
- [ZT]MapReduce explained in 41 wordsAI
- iptables新增模組(for kernel 2.6)(轉)
- [轉載]P2P GroupSpecifier Class Explained In Details Part 1AI
- Csscan output explained [ID 444701.1]CSSAI
- linux kernel 2.6.11.12(轉)Linux
- bootsplash for slackware kernel-2.6.12!(轉)boot
- Linux Kernel V2.6.15.5(轉)Linux
- kernel hacking簡單入門(轉)
- Slackware 10.0 Kernel ??後的流程(轉)
- Linux Kernel ACL訪問控制漏洞(轉)Linux
- 製作RAMDISK in KERNEL的OpenBSD微系統(轉)
- Linux kernel 'getting buggier'[英文](轉)Linux
- kernel 2.6下上網慢的解決(轉)
- Bash One-Liners Explained (二):操作字串AI字串
- Linux Kernel 2.6 核心執行緒嚐鮮(轉)Linux執行緒
- 製作RAMDISK in KERNEL的NetBSD微系統(轉)
- 在Linux Kernel內新增一個System Call(轉)Linux
- 關於核心執行緒(kernel_thread)(轉)執行緒thread
- 著名美國電信公司招聘linux kernel engineer(轉)Linux
- 核心引數kernel.shmall和kernel.shmmaxHMM
- 解決掛起/休眠時遭遇kernel panic問題(轉)
- Bash One-Liners Explained(一):檔案處理AI
- Linux Kernel2.6x 最新本地溢位程式碼(轉)Linux
- Linux Kernel File IO Syscall Kernel-Source-Code Analysis(undone)Linux
- 向kernel module 傳遞引數(Passing Arugments to Kernel Module)
- Document TitleTECH: Unix Semaphores and Shared Memory Explained (Doc ID 15566.1)AI
- Linux kernel mapLinux
- kernel 啟動流程
- LangChain vs Semantic KernelLangChain
- Linux Kernel(核)Linux
- Unix kernel parameters for OracleOracle
- TECH: Unix Virtual Memory, Paging & Swapping explained (Doc ID 17094.1)APPAI
- ORA_NLS (ORA_NLS33, ORA_NLS10) Environment Variables explainedS3AI
- Laravel kernel例項化Laravel
- kernel wifi 測試方法WiFi
- 【PingCAP】Database Kernel EngineerPingCAPDatabase