至此,你應該明白16位Windows的記憶體管理器是如何處理全域性堆了。是時候來進入32位的Windows的世界了。
到了32位之後,GlobalAlloc會繼續和之前一樣模擬所有記憶體移動規則,但是GlobalAlloc的返回值不再是一個選擇子(Selector),因為在Win32中,處理器是執行在平坦地址模式(Flat Mode)。
這意味著,之前快取選擇子並在底層重新分配記憶體的技法不再有效。
記憶體的移動性語義被完整地保留下來。記憶體塊依然會有一個屬性叫做鎖定計數,即使它並沒有什麼意義,因為Win32系統從來都不會對記憶體進行壓縮(請回憶一下,鎖定計數是用來防止記憶體在壓縮期間進行移動的一個屬性)。
如果不是為了照顧GlobalFlags這個函式,可移動記憶體和鎖定計數可以被完全地從系統中移除。GlobalFlags會返回一些奇怪的位資訊模式,但現在這些資訊都和記憶體不相關了,唯有鎖定計數這一項資訊。所以,鎖定計數依然保留,以防止有一些應用程式會使用到它,或者一個程式會預期GlbalReAlloc會在一個已鎖定的記憶體塊上執行失敗。
除此之外,一塊可移動記憶體除了上述的開銷之外,並不能給你帶來什麼其他的東西。
另外一個函式,LocalAlloc也是一樣,它依然會帶有記憶體移動性的操作開銷,但是因為在Win16上,本地記憶體不會在DLL之間傳遞,所以本地堆相關的函式不會像全域性堆那樣會帶有16位相容性開銷的問題。
在Win32上,基於上面的原因,推薦使用LocalAlloc。
(當然了,很多函式在記憶體分配時,需要指定一個特殊的型別,這個時候,你就不會有太多選擇。例如,剪貼簿就需要一個可移動的全域性控制代碼,另外,COM需要使用一個任務分配器)
接下來,我們將會關注記憶體的鎖定是如何實現的(雖然它也不會做什麼有實際意義的操作)。
總結
拓撲梅爾智慧辦公平臺(Topomel Box):還是Win32對我們好,API豐富,相容性也好,文件又全面。
Win11:還沒好夠…(DOG)
最後
Raymond Chen的《The Old New Thing》是我非常喜歡的部落格之一,裡面有很多關於Windows的小知識,對於廣大Windows平臺開發者來說,確實十分有幫助。
本文來自:《A history of GlobalLock, part 3: Transitioning to Win32》