為何微軟不在新的操作系統中讓 32 位支持大於 4GB 的內存?
在win7時期,4GB內存已很常見,常常有人為了使用更大的內存而使用64位操作系統,現在Windows 已經到 8.1了,為什麼32位系統還是不支持大於4GB內存,而在伺服器版Windows Server 2003 的32位系統就可以最高支持32GB內存。為何不將這個技術運用到桌面版的操作系統中?
先給一個參考文獻:The RAM reported by the System Properties dialog box and the System Information tool is less than you expect in Windows Vista or in Windows XP Service Pack 2 or later version
先說結論:
1、PAE允許操作系統在32位模式下使用大於4G的物理內存。
2、不管是否使用PAE,對於單個進程而言,32位系統下可見的地址空間最大只有4G。
3、PAE的優勢是可以讓不同的進程(在不同的地址空間里)累計使用大於4G的內存,因此而達到使用超過4G內存的目的。
4、WindowsXP系列雖然支持PAE,但實際在使用中最大內存限制在了4G,是人為限制的,原因後面給分析(樓上給出的各種理由都不成立,這裡是有技術原因的)。
5、Linux則在開啟PAE的模式下能支持在32位系統中使用超過4G的內存。
然後給原因,其實就是我最初給的鏈接里的內容:
This issue occurs because of a design change in Windows XP SP2 that is also included in Windows Vista. The changes were made to PAE mode behavior to improve driver compatibility.
To reduce driver compatibility issues, Windows Vista and Windows XP Service Pack 2 or a later version include hardware abstraction layer (HAL) changes that mimic the 32-bit HAL DMA behavior. The modified HAL grants unlimited map registers when the computer is running in PAE mode. Additionally, the kernel memory manager ignores any physical address that is more than 4 GB. Any system RAM that is more than the 4 GB barrier would be made unaddressable by Windows and be unusable in the system. By limiting the address space to 4 GB, devices with 32-bit DMA bus master capability will not see a transaction with an address that is more than the 4 GB barrier. Because these changes remove the need to double-buffer the transactions, they avoid a class of bugs in some drivers that is related to the correct implementation of double buffering support.
英文比較長我大概解釋一下(以下僅限x86-32/64bit平台,不考慮其它arch):
首先要先科普一下DMA:DMA的意思可以大概理解為:讓硬體(比如顯卡、音效卡、USB、磁碟控制器等)直接操作物理內存,等操作完成以後返回一個中斷給操作系統,告訴操作系統說我幹完了。
DMA的好處就是:假如我想要往磁碟上寫數據,數據已經在內存里了,那麼CPU只需要把內存地址告訴磁碟控制器,剩下就不用管了,磁碟控制器完成寫操作以後會告訴CPU說寫完了,這個期間不耽誤CPU做其它的事情。
DMA跟4G內存有什麼關係?當然有關係了,因為不是所有內存都是隨便都能做DMA的。
如果寫過64位操作系統的驅動的話,應該會了解到:有一些外設是無法訪問超過4G的內存地址的,有些外設做DMA的時候,能訪問的地址都是4G以下的地址(如果我沒記錯,USB-EHCI控制器好像就是這樣的)。
因此在64位操作系統里,所有DMA操作都是先專門申請一塊專門的DMA內存(4G以下),然後再進行操作。而32位系統里,則一般沒有這個限制。
好了,問題就來了:
微軟的XP是十幾年前的操作系統,在當時的硬體環境里,所有內存都是可以做DMA的。所以在XP的內核API里,沒有考慮過內存不能DMA的情況,所以,XP里的各種驅動、軟體在寫代碼的時候,也都沒有考慮過內存能不能DMA,只要拿來用就是了。
而十幾年間,硬體發生了翻天覆地的變化,而XP由於其強大的兼容性,這方面的API一直都沒改進。況且,想改進也不行,因為必須二進位兼容舊代碼,並且由於這個兼容性的問題從XP一直延續到了Vista,所以包括Win7在內的各種版本,都必須保持這個兼容性。
二進位兼容這個巨大的包袱使得MS如果真使用了大於4G的內存,那麼很有可能出現藍屏之類的異常情況,因為微軟也不知道用戶的驅動代碼是怎麼寫的,會不會直接使用內存進行DMA。
所以,微軟強行把內存限制在4G以下是為了保持可恨的兼容性。
如果放棄了兼容性可不可以?當然可以了,但那就不是XP而是另一個版本的Windows了。
為什麼Server版一直都支持超過4G的內存?因為Server版的驅動跟普通版的不兼容。
所以樓上的所有解釋都是不對的,不是市場定位或者照顧用戶情緒或者不想讓用戶這麼做,而是因為兼容性無法保證DMA正確執行(微軟也解釋的很清楚了,但是國內用戶似乎沒人注意)。
有人提了Ready For 4G,這東西會導致某些程序異常,原因就是這些程序在運行中嘗試直接使用物理地址(很多軟體就是這麼流氓),而代碼中獲得的物理地址都是32bit的,在某些情況下代碼中獲得的地址不是實際的物理地址,而導致程序崩潰,說實話,沒藍屏已經很不錯了。
如果要讓Windows支持超過4G內存,那麼幾乎所有驅動都要重寫一遍,這裡還包括操作系統中運行的大量第三方未簽名的驅動,這麼大的負擔顯然是誰也承擔不了的,因此在32位系統上無法使用4G內存。所以,不是不想,是不能。
評論里有人提出,如果專門識別一下驅動,對於非認證的驅動強制限制在4G以下,認證過的驅動允許使用高於4G的地址,這樣是否可以?
答案是可以的。問題是這麼做代價很大,內核中各個API都要多一條甚至幾條檢查路徑來判斷驅動的情況,甚至還要小心驅動代碼直接用non-paged內存搞DMA,這麼做效率就是一個問題,而且微軟是無法拿到所有驅動的源碼的,比如顯卡廠商一般就只發布binary的驅動,所以,微軟無法知道這個驅動里究竟搞了什麼小動作。所以不得不把這條路堵死。
通過PAE完全可以使用超過4G的RAM,只不過在windows桌面版本把這個功能禁用了。
幾年前就在遠景論壇放出過修改後的nt kernel,效果確實可以支持4g以上。只要改動kernel幾個位元組就行。有興趣的自己搜一下就可以了。
至於原因,我詢問過kernel組的同事,回答是當時桌面系統上的各種奇葩驅動太多了,很多在PAE下有bug。如果藍屏了用戶肯定罵微軟。而server版本上運行的驅動整體質量較高,所以沒什麼問題。感謝邀請。這個問題是這樣子的,32位的大限就是4G,這個是一個無法改變的事實,通過什麼技術手段都無法改變。每一個32位進程都獨享4G的虛擬地址空間,其中低2G是給用戶的,高2G是給系統預留的。也就是每一個32位進程中,實際能夠使用的內存不到2G。
但是應用程序對於內存的需求總是無止境的,恨不得所有東西都存在內存裡面,完全沒有磁碟IO。微軟對於32位系統有兩種使用更大內存的方法。一種是4GT,就是為了讓應用程序能夠使用更多的內存,壓榨一下操作系統保留的地址空間,也就是低3G留給用戶,高1G給系統保留,也就是能夠利用的內存空間僅僅多了1G而已。但是這種情況,操作系統支持的總物理內存大小沒有改變。
另外一種是上面有人提到的PAE,PAE這種支持大內存的方法,也並不能真正解決對於大內存的需求。首先PAE需要硬體支持,也就是CPU具有支持PAE的相關指令。其次,也是最重要的,PAE不能改變每一個進程的虛擬地址空間4G的上限,而是使得操作系統能夠分配的物理內存更多一些而已。也就是說,雖然操作系統支持的物理內存總量可以達到32G,但是每一個進程能夠使用的最大內存空間也還是2G,開啟4GT之後能夠達到3G,然後就上不去了。這種利用大內存的方法對於普通用戶並不是非常有意義。畢竟伺服器上還可以這樣,6G內存中,2G給資料庫(進程),2G給緩存(進程),2G留給操作系統的其他服務,通過多個進程瓜分大內存。普通家用系統,玩遊戲是單獨的遊戲進程需要大量的內存,而這種情況即使使用PAE也是解決不了的。
所以,如果我們對於內存的需求,是單個進程需要使用大量的內存,那麼32位根本不能滿足我們的需求,什麼樣的技術手段都不能夠改善。只有升級到64位系統才能夠解決這個問題。如果要想在32位系統上充分利用大內存,只能夠使用多進程,但是對於大部分需要使用大內存的應用,這種方式也很不靠譜,不同進程之間通信的效率並不高,開發起來還很麻煩,也就是像Chrome這樣多進程的程序才能夠利用了。
如果微軟在非伺服器版本中啟用PAE支持4G以上的內存,按照現在輿論的風氣,一定會被罵出翔。為什麼明明我配了16G的內存也還是玩不了這個內存需求只有4G的遊戲啊!!微軟你這個大垃圾!!!
像這樣的抱怨一定到處都是,微軟費力不討好,何必呢?
Memory Limits for Windows Releases (Windows)拿個最簡單的例子,任天堂的FC機。
FC機的CPU是基於6502的2A03,它有16條地址線,8條數據線,其地址空間為$0000-$FFFF,共64KiB。
這條地址匯流排上的一個重要節點就是卡帶插槽
FC最初的遊戲卡帶在設計的時候,16條地址線中有15條連接到卡帶上,以最高位為片選,分別取14條連接到兩塊16KiB的ROM晶元,映射到地址空間高32KiB,稱為BANK0和BANK1。而且,卡帶插槽還有一條專門的片選線用於選取地址空間低32KiB的一片8KiB大小的區域作為卡帶擴展RAM用。另外,主機的PPU圖形處理器另有一套16位地址,8位數據的定址系統,但在卡槽中僅有13條PPU地址線,映射到8KiB的PPU ROM。
在1983年這樣的設計還是比較充分的,但到1985年後,FC出現了多種擴展配置,出現了更大容量的媒體。比如簡易BASIC編程環境Family BASIC(後來小霸王的G-BASIC的原版)使用了卡帶擴展RAM+記憶電池用來保存程序,FC磁碟機將BANK1的高8KiB用於存放其固件ROM,之前所有空間包括卡帶擴展RAM空間共32KiB用來緩存磁碟中讀取的遊戲程序。但是,FC磁碟機由於太過容易盜版,最終並沒有成為FC標準的大容量存儲媒體。
這時候(大約在86年),任天堂和其它遊戲公司都想出了新的存儲大容量遊戲的手段。那就是,在卡帶中使用64KiB,128KiB甚至更大容量的ROM晶元,在卡帶上實現一個BANK切換器(模擬器中說的Mapper),通過一些手段(如內存特定地址的值等)與CPU進行通信,在地址匯流排BANK0、BANK1中邏輯地址與ROM晶元物理地址之間建立映射關係,稱之為BANK切換,以達到支持遠遠大於32KiB的大型遊戲的目的。至於PPU用的ROM部分,有些卡帶上把它做成RAM,由CPU通過IO埠在運行時寫入PPU數據(比如美版的魂斗羅、惡魔城、塞爾達傳說等遊戲),有些則和CPU ROM一樣進行BANK切換(如超級魂斗羅,馬里奧3代等遊戲)。在1994年FC停產時,通過BANK切換,FC能支持總容量最大達1024KiB的遊戲;而大陸及台灣D商,利用後來的單片機技術和大容量NOR Flash製作的超大容量合卡甚至能達到16MiB,21世紀更有卡帶部分複雜度超FC本體整個電路多倍的燒錄卡NES PowerPak等的出現。
但是,五花八門的BANK切換器,無法改變一個事實:FC的定址空間仍然只有16位,$0000-$FFFF,你想訪問當前不在定址空間內的數據,就必須切換BANK,這需要一系列複雜的操作和開銷。
現代PC的地址線當然遠遠不止32條,但是i386的虛擬內存模型下,你只有00000000-FFFFFFFF的虛擬空間可用。而PAE基本上都是在有內存保護的分頁式內存模型情況下的實現,需要操作一個頁目錄指針表,而它必須是內核模式下才能直接操作,用戶模式下的程序要想通過PAE來實現類似FC的BANK切換的效果,就必須用到操作系統提供的用戶模式介面(如Windows的AWE),而它們一般有很多限制。加之PAE出現得很早(Pentium Pro就已經出現),而能用完32位地址空間的應用程序直到2005年之後才大量出現,因此很多開發者根本就忽視了這一套東西的存在,導致PAE的潛力無法完全發揮出來。而且,系統通過PAE支持超過4GiB以上RAM,不僅需要系統內核本身的支持,而且需要所有的驅動程序、主板BIOS和硬體的支持,在普通PC中很難完全滿足這些條件,因此,微軟在客戶級32位操作系統中乾脆就選擇了屏蔽4GB以上的物理內存空間。
windows server 2003通過PAE技術支持超過4G的系統內存只是在那個64位x86處理器尚未普及的時代的權宜之計。如今絕大多數PC的處理器都是64位的,就連ARM指令集也邁入了64位時代,需要大內存的windows用戶並不會面臨沒有64位處理器可用的尷尬;與此同時,64位操作系統對32位軟體的兼容性也已經非常好了,所以用戶無需繼續留在32位平台上,直接遷移到64位平台即可獲得完整的大內存支持能力。
- ,這是 32 位下單進程內存上限,你總內存支持的再多也沒用
- 很多 32 位驅動無法處理超過 4GiB 的地址空間
- 現在 Windows Server 只有 x64
- 不要低估 C++ 程序員的愚蠢
很久沒有用32位系統了,不過從微軟官方說明來看,已經強制啟用了。
「物理地址擴展 (PAE)、NX 處理器位 (NX) 和流式處理 SIMD 擴展 2 (SSE2) 是處理器的功能,需要它們才能運行 Windows 8.1。
……
PAE 使 32 位處理器能夠在具備相應能力的 Windows 版本上使用超過 4 GB 的物理內存,是使用 NX 的一個前提條件。
……
如果你的電腦不支持 PAE、NX 和 SSE2,就無法安裝 Windows 8.1」
額,沒看到準確的答案噻。
其實吧PAE可以很容易的開啟,這不是家用系統不能用4G以上內存的原因,只是Windows 7/Vista等就算開了PAE,還有系統許可(話說32位Windows還有一些Starter版本限制只能用1G 2G內存)的限制http://www.geoffchappell.com/notes/windows/license/memory.htm沒法用4GB以上,倒是可以用Ready for 4G破解或者RAMDISK之類建立內存檔。
反正我也不知道微軟怎麼想的,也許開了PAE可能會導致一些寫的不規範的驅動或者程序崩潰吧,寫的規範的應該沒事,但在天朝,朋友用ready for 4G 用9G內存上QQ就會崩潰(貌似qq和r4g不對付),輕則windows系統,重了ESX Server都玩完。
關於32位系統單進程最大內存,32位系統單應用程序最大內存可以超過2G,NT下內存map時可以增加到3G(需要設置,還需要程序為此編程),而通過Windows的AWE APIs,可以利用到最大64G內存(SQL是這麼乾的)。
補充點這裡沒有的東西好了,intel保護模式下的頁交換還有個PSE 36模式,在NT5時 可以通過這個支持最大2^40內存。與PAE不同。性價比太低。既然64bit直接支持大內存,何必要32bit的系統,目前硬體成本如此之低,這樣只會無謂的增加軟體成本,完全是倒行逆施。
反對樓上答案,32位理論支持最大4GB內存不錯,但是Intel早就推出了PAE可以擴展到64GB(36位地址)。
這種東西只要查文檔就知道了,Physical Address Extension (Windows)Windows automatically enables PAE if DEP is enabled on a computer that supports hardware-enabled DEP, or if the computer is configured for hot-add memory devices in memory ranges beyond 4 GB. If the computer does not support hardware-enabled DEP or is not configured for hot-add memory devices in memory ranges beyond 4 GB, PAE must be explicitly enabled.
我的翻譯比較渣,上面的英文也很好懂。
所以你的電腦並不滿足自動啟用PAE的兩個條件之一,所以Windows不會自動啟用,要你自己手動啟用。計算機內部是二極體,通過高電平和低電平(或稱有電壓和無電壓)來表示信息,用數學的方法解釋就是1和0,如果要表示複雜的信息,就需要多個高低電平來表示數據,比如52個大小寫字母和10個數字就是用8位高低電平顯示,01000001是A,01000010是B,我們看到8位的極限就是2的8次方也就是256個,漢字怎麼辦?日文怎麼辦?就用2個8位也就是16位來組成,比如「中」字在內部是1000001000111011來表示。
通過上面可以理解位的概念,所謂32位就是傳輸的時候,對應的傳輸的地址匯流排也是32根,它只能表示2的32次方不同的數據(狀態),可以理解為內存中有有2的32次方的房間,中央處理器對內存說我要訪問第XXX號房間的數據,XXX最大為2的32次方,你有多餘的房間,可惜我叫不出名字,除了把名字再拉長。
2的32次方 = 4294967296 = 4194304k(1k是1024) = 4096M(1M是1048576) = 4G(1G是1073741824)
看了樓上這麼多人說32位只能支持4G內存,我實在是看不下去了。
單個進程里只有32位的地址空間,所以單個進程是最多只能用4G內存,但這並不影響32位的系統使用超過4G的內存。又不是要把所有的內存分配給一個進程不是?
10多年前的PC主板都支持40位定址,XP的內核是64位管理內存的(其實沒有64位,高几位做標誌位去了)。所以32位的Windows Server 2003就可以用幾十G的內存。至於為什麼微軟不想讓32位的桌面系統支持4G以上的內存,拜託,人家現在都希望大家不要用32位系統了好不好?
對XP系統原理做個大致解釋,以紀念即將結束的XP時代。
1. 虛擬模式和實模式。
在DOS/8086時代,系統定址是直接由程序指定一個數(地址),然後CPU就去找這個編號的內存來取數。進入80286之後,系統增加了虛擬模式,也叫做保護模式。虛擬模式是應用程序指定一個內存地址,CPU接到這個地址後會查找地址翻譯表(名稱不是御用名稱),找到這個地址對應的物理內存地址,如果不存在對應的物理內存,則觸發缺頁中斷,由操作系統的缺頁中斷處理程序從硬碟中的虛擬文件中調入相應的數據並完成地址翻譯表的修改,返回後繼續執行指令,這時你會看到操作系統的延遲。
2.32位Windows內存模型(虛擬地址)
Windows將應用程序局限在一個段中,即CS=DS=ES=SS,我不知道是不是有硬體上的限制,但是估計是微軟自己的限制,因為從哪個方面看4G都夠用了。微軟認為4G還是太多了,所以微軟又攔腰截了一半,低位的4M作為16位程序(包括DOS、DOS的PAE擴展、Win3.x)使用,之上的地址到2G是應用程序的地址,高位的2G是共用地址,即所有程序的高位2G都會被映射到相同的物理地址上(或硬碟的虛擬內存文件),這是Win98(保護模式開的不是很嚴格)能讓一個應用程序將整個系統搞藍屏的原因。
3.物理地址的極限。
物理地址由CPU以及配套的地址匯流排決定,8086有20條地址線,所以其能管理的內存空間是1M,80286的地址線為24條,所以能管理的內存空間是16M。奔騰以後的機型的地址線應該在36條以上,能管理的內存空間為64G
4.PAE與虛擬地址的極限
32位系統中,段址寄存器是16位,寄存器是32位的,由段址寄存器+寄存器形成的地址空間是48位的,其中一位保留為全局標識符,兩位保留為許可權標識符(從00到11,此處的11表示3),其中操作系統運行在0環,應用程序運行在3環。所以為45位,可以定址的範圍為32TB,已經大於任何一個單體硬碟的容量了吧?太大了,所以微軟將應用程序的段址設定為一個唯一數,那麼虛擬地址(又叫做邏輯地址)的空間就變成了4G(不再敖述)。但是對於整個系統而言,依然可以表示32T(有一半的地址是映射為相同的物理地址的)
對於16位的虛擬模式,情況是類似的,但是對於實模式,則是不同的。在實模式下,地址形成的方式是段址寄存器×16+寄存器(BP、SP、SI、DI、BX,其他的寄存器不可以),也就是說空有24條地址線,但是寄存器組合只能表示20條地址線的空間(加了地址線,但是沒有改CPU的指令),所以高於1M的地址是沒有辦法用的。DOS想的辦法是提供PAE驅動程序,如果程序(注意實模式下的應用程序跟操作系統的許可權是一個級別的),即如果程序要使用更多的內存,則需要調用PAE驅動程序,PAE驅動程序將系統轉換為虛擬模式,從擴展內存中複製信息,或寫入擴展內存中,然後再返回實模式
5.為什麼XP不能使用4G以上內存
目前排名第一的應該是正確的,即DMA定址範圍就是4G空間,而且使用的是物理地址(以提高效率),所以對於4G以上的地址,無法直接使用DMA。XP的追加包採用了硬體抽象的方法解決了這個問題。
沒用的,32位系統的虛擬地址只能是4g,設備的內存映射都是在4g地址以下,就算支持4g,以前設備相關的驅動估計就要重寫了
微軟大概是覺得不值得在64位潮流到來的情況下,為既有系統打這個補丁。說32位=4g的可以拿塊硬碟面壁去,fat16就支持64k的硬碟嗎?
windows虛地址空間,頁式內存管理機制很容易突破4g的限制。
內存突破「物理」極限不是沒有先例,可以查查16位機的20位地址線模式,隔得並不遠。
http://www.cnblogs.com/dolphin0520/archive/2013/05/31/3110555.html
推薦閱讀: