深入SQL SERVER 2000的內(nèi)存管理機(jī)制(二) http://msdn.microsoft.com/data/default.aspx?pull=/library/en-us/dnsqldev/html/sqldev_01262004.asp
可訪問大地址的應(yīng)用 (Large-Address-Aware Executables)
在Windows增加支持/3GB參數(shù)以前,一個(gè)應(yīng)用程序是無法訪問一個(gè)帶有高位設(shè)置的指針.一個(gè)32位的指針只有前31位地址空間可以被用戶模式的應(yīng)用程序訪問.這剩余的一位不用.因此有一些聰明的開發(fā)者因?yàn)槠渌哪康牟辉敢庠谔幚韮?nèi)存地址空間時(shí)浪費(fèi)這一位.(舉例來說:可以用來標(biāo)志一個(gè)指針引用其它應(yīng)用程序分配的數(shù)據(jù)類型).這樣就/3GB參數(shù)就遇到一個(gè)難題,因?yàn)檫@種類型的程序不能方便的區(qū)分一個(gè)合法的指針引用的內(nèi)存空間在2G的分界線以上與一個(gè)內(nèi)存地址空間在2G以下,但它的高位已經(jīng)被用做它用的指針.基本上如果一臺(tái)機(jī)器用/3GB的參數(shù)啟動(dòng),這種應(yīng)用程序是無法運(yùn)行的.為解決這種狀況,微軟在WIN32的PE文件Characteristics字段增加了一個(gè)新的標(biāo)志位來表示一個(gè)程序是否運(yùn)行在可訪問大地址的(Large-Address-Aware Executables)模式.當(dāng)該標(biāo)志位被起用( IMAGE_FILE_LARGE_ADDRESS_AWARE ),該可執(zhí)行文件頭部Characteristics字段的32位被置位.通過這個(gè)可執(zhí)行文件頭部的標(biāo)志位,應(yīng)用程序可以暗示WINDOWS 它可以處理帶有高位設(shè)置的指針,這樣就不會(huì)帶來任何異常結(jié)果.當(dāng)該標(biāo)志被置位并且支持這種方式啟動(dòng)的Windows也是通過/3GB的參數(shù)啟動(dòng),這時(shí)操作系統(tǒng)會(huì)提供一直擴(kuò)展的私有用戶模式的地址空間給應(yīng)用程序.你可以通過工具,比如: DumpBin 和 ImageCfg (轉(zhuǎn)儲(chǔ)可執(zhí)行文件的頭部)來檢查一個(gè)可執(zhí)行文件的該標(biāo)志位.Visual C++ 通過 /LARGEADDRESSAWARE 連接器開關(guān)來表示IMAGE_FILE_LARGE_ADDRESS_AWARE,SQL SERVR已經(jīng)將該標(biāo)志位激活,所以你可以在支持/3GB參數(shù)的Windows 版本中使用該參數(shù),這樣操作系統(tǒng)回自動(dòng)擴(kuò)展SQL SERVER的用戶內(nèi)存空間.
注釋:Windows在可執(zhí)行文件啟動(dòng)時(shí)檢查IMAGE_FILE_LARGE_ADDRESS_AWARE 標(biāo)志位,但忽略DLL文件.DLL代碼必須自動(dòng)處理高位被置位的指針。
物理內(nèi)存擴(kuò)展
Intel 處理器自從Pentium PRO開始,以后的處理器都支持一種物理內(nèi)存擴(kuò)展(PAE)的內(nèi)存映射模式。PAE模式提供了可以訪問64GB的物理內(nèi)存空間。在PAE模式中,內(nèi)存管理單元(Memory Management Unit (MMU))仍然執(zhí)行:頁(yè)目錄入口page directory entries(PDEs) 和頁(yè)表入口page table entries (PTEs),但是在此之上有一個(gè)新的級(jí)別:頁(yè)目錄指針表。同時(shí),在PAE模式PDEs 和PTEs是64位的(不僅僅是標(biāo)準(zhǔn)的32位),這樣系統(tǒng)可以映射比標(biāo)準(zhǔn)轉(zhuǎn)換更多的內(nèi)存空間,因?yàn)?/SPAN>PDEs 和PTEs模式的尋址寬度是標(biāo)準(zhǔn)的2倍。這并不僅僅是增加了頁(yè)目錄指針表。頁(yè)目錄指針表被用來管理這些大容量表和索引。一些特殊版本的Windows內(nèi)核需要運(yùn)行在PAE模式。這中內(nèi)核集成在Windows 2000以及以后的版本中,在單處理器的機(jī)器中體現(xiàn)在Ntkrnlpa.exe文件中,在多處理器的機(jī)器中體現(xiàn)在Ntkrnlpamp.exe文件中。你可以向增加/3GB和/USERVA參數(shù)一樣在BOOT.INI文件中加/PAE參數(shù)激活PAE模式。
地址窗口擴(kuò)展
Windows的地址窗口擴(kuò)展(AWE)機(jī)制可以允許應(yīng)用程序訪問超過4GB的物理內(nèi)存。一個(gè)32位的指針是一個(gè)整數(shù),只能保存0x00000000到0xFFFFFFFF的值,就是說可以引用4GB 以內(nèi)線性的內(nèi)存地址空間,AWE允許一個(gè)應(yīng)用程序繞過這些限制,通過操作系統(tǒng)訪問所有的內(nèi)存空間。
從概念上說,AWE并不是一個(gè)新的事物。在計(jì)算機(jī)發(fā)展之初,操作系統(tǒng)和應(yīng)用程序已經(jīng)使用相似的機(jī)制回避指針的限制。例如:我們倒退到DOS年代,32位擴(kuò)充功能被經(jīng)常用來允許一個(gè)16位的程序訪問他自已以外的內(nèi)存地址空間。一些特殊目的管理者和API經(jīng)常使用擴(kuò)充內(nèi)存和擴(kuò)展內(nèi)存。你可能記得這樣一個(gè)很久以前產(chǎn)品Quarterdeck QEMM-386經(jīng)常用來做這樣的事情。典型的機(jī)制是允許一個(gè)指針可以訪問超過本身限制的空間,(比如:地址太大無法在自己的指針中)通過在可以訪問的地址空間分配一個(gè)窗口或區(qū)域來和本身無法訪問的內(nèi)存地址之間傳遞指針。AWE的工作原理:你可以在可以訪問的地址空間提供一塊區(qū)域(窗口)作為分段傳輸區(qū),來傳送在用戶內(nèi)存空間無法訪問的內(nèi)存地址。
為了使用AWE,一個(gè)應(yīng)用程序需要:
1. 分配的物理內(nèi)存地址可以通過AllocateUserPhysicalPages API函數(shù)訪問。這個(gè)函數(shù)需要調(diào)用者有Lock Pages in Memory的權(quán)限。
2. 在可以訪問的內(nèi)存空間建立一塊區(qū)域。通過VirtualAlloc API函數(shù)可以作為映射一個(gè)物理內(nèi)存的映射窗口。
3. 通過MapUserPhysicalPages 或MapUserPhysicalPagesScatter WIN32 API 函數(shù)完成物理內(nèi)存和虛擬內(nèi)存的映射。
AWE已經(jīng)存在于所有的Windows 2000和以后的操作系統(tǒng)中,甚至可以用于物理內(nèi)存低于2GB的操作系統(tǒng)中,最典型的應(yīng)用是在2GB或以上物理內(nèi)存的機(jī)器上,因?yàn)檫@是一個(gè)32位處理器訪問3GB以下內(nèi)存空間的唯一方法。如果你在一個(gè)低于3GB物理內(nèi)存的SQL Server系統(tǒng)中激活AWE支持,系統(tǒng)將忽略這個(gè)選項(xiàng)同時(shí)轉(zhuǎn)換為虛擬內(nèi)存管理器代替。AWE內(nèi)存有一個(gè)有趣的特征就是從不和磁盤交換數(shù)據(jù)。你也許注意到特有的AWE API程序引用可以訪問的內(nèi)存空間是作為物理內(nèi)存訪問。這點(diǎn)確切的說就是:AWE內(nèi)存是不和系統(tǒng)的虛擬頁(yè)面文件交互物理內(nèi)存空間。
虛擬內(nèi)存窗口被用來緩存AWE讀寫訪問物理內(nèi)存的請(qǐng)求。因此,當(dāng)你配置這個(gè)窗口是PAGE_READWRITE唯一可以保護(hù)的特征就是轉(zhuǎn)嫁給了VirtualAlloc API函數(shù)。不要驚奇,這也意味你不能用VirtualProtect API函數(shù)來保護(hù)這塊內(nèi)存區(qū)域的修改和訪問。
注釋:還沒有專門的工具用來調(diào)查應(yīng)用程序AWE內(nèi)存使用(任務(wù)管理器,性能監(jiān)視器和監(jiān)視系統(tǒng) 等等),顯示每一個(gè)程序AWE內(nèi)存的使用數(shù)量。這樣就沒有每個(gè)程序使用AWE內(nèi)存數(shù)量的軌跡,同時(shí)這些內(nèi)存也沒包括在每個(gè)的程序的工作內(nèi)存集中。
/3GB 和AWE比較
增加用戶程序地址空間的能力幾乎有50%的應(yīng)用程序是通過內(nèi)存調(diào)整,這是在Windows內(nèi)存管理機(jī)制當(dāng)中非??旖莺褪軞g迎的手段。而且Windows AWE內(nèi)存機(jī)制也是非常靈活和穩(wěn)定的。就像我前面所說的,當(dāng)你增加1G的用戶內(nèi)存空間,這些內(nèi)存是通過減少核心內(nèi)存空間獲得的(從2G減到1G)。因?yàn)楹诵拇a的運(yùn)行對(duì)整個(gè)內(nèi)存空間來說是很狹窄的一塊即使用于2G的空間,收縮這些內(nèi)存空間意味著內(nèi)部核心架構(gòu)也會(huì)收縮。其中最重要的是windows用來管理物理內(nèi)存的表,當(dāng)你收縮核心內(nèi)存空間到1G,你就限制了這個(gè)表的大小,這樣只能管理最大16GB的物理內(nèi)存。例如:如果你的應(yīng)用程序運(yùn)行在有64GB物理內(nèi)存的SERVER上并且你在啟動(dòng)時(shí)加了/3GB的參數(shù)。你只能訪問整個(gè)內(nèi)存的25%的空間—其余的48GB的內(nèi)存空間無論時(shí)操作系統(tǒng)還是應(yīng)用程序都無法訪問。AWE可以允許你訪問比加/3GB參數(shù)更高的內(nèi)存空間。顯然,你通過/3GB的參數(shù)只是增加了1GB的用戶內(nèi)存空間,這些增加的內(nèi)存空間只是對(duì)那些大地址自動(dòng)獲得的應(yīng)用程序有效,但是只有1GB。和/3GB參數(shù)對(duì)比,AWE可以使整個(gè)的物理內(nèi)存對(duì)操作系統(tǒng)有效和對(duì)使用AWE WIN32 API的應(yīng)用程序有效。因此,AWE使用和操作起來更加復(fù)雜,也更加靈活和可擴(kuò)展。
著并不是說/3GB比AWE更好是不存在的-不過這確實(shí)存在,比如:如果你需要分配更多的內(nèi)存空間,但不能在AWE中分配(線程堆棧,內(nèi)存鎖,過程計(jì)劃),你也許發(fā)現(xiàn)/3GB回更好一些