内存体系 用共享段于进程间联系
內存體系結構
虛擬地址分區:空指針賦值分區,用戶模式分區,64KB禁入分區,內核模式分區
在默認情況下運行一個64位的應用程序,系統會保留用戶模式地址空間中位于地址0x00000000'80000000(2G)之后的所有部分;
這確認所有的內存分配在低2G上,這就是所謂的地址空間沙箱,可以用Yes (/LARGEADDRESSAWARE) link開關打開。dll工程會忽略此開關。
當系統創建一個進程并賦予它地址空間時,調用VirtualAlloc來預訂,再還是通過VirtualAlloc來調撥物理內存與之映射。用VirtualFree來撤銷調撥。
當應用程序調用VirtualAlloc函數來把物理存儲器調撥給地址空間區域時,該空間實際上是從硬盤上的頁交換文件分配得到的。
當用戶要求執行一個應用程序時,系統會打開該應用程序對應的.exe文件并計算應用程序的代碼和數據的大小,然后系統會預訂一塊地址空間,并注明與該區域
相關聯的物理存儲器就是.exe文件本身。系統不會從頁面交換文件中調撥物理內存,因為這樣拷貝代碼與數據到頁面交換文件中,這是低效的。此時的EXE文件也叫內存映射文件。
可以為每個物理存儲頁指定不同的頁面保護屬性。非閑置區域的基地址都是64KB(分配粒子)的整數倍。
地址空間中區域類型:
閑置:未預定
私有:以頁面交換文件為后備存儲器
映像:一開始以映像文件(EXE或DLL文件)為后備存儲器,后來如果寫入映像文件一個全局變量,那么寫時復制會改用頁交換后備存儲器。
已映射:一開始以內存映射文件為后備存儲器,后來內存映射文件可能會使用寫時復制保護屬性,任何寫操作會改用頁交換后備存儲器。
為節省磁盤空間,鏈接器會盡可能地對所生成的PE文件進行壓縮。當WINDOWS將PE文件映射到進程空間時,每一段(SECTION)必須另起一頁,而且起始地址為系統頁面的整數倍。
如果程序試圖寫入區域中具有PAGE_WRITECOPY或PAGE_EXECUTE_WRITECOPY屬性的頁面,那么系統會專門為進程復制一份該頁面。
第14章 操作系統的許多系統信息是由系統所運行的主機決定的,如頁面大小和分配粒度等。GetSystemInfo(LPSYSTEM_INFO psi)
為了讓32位的應用程序也能在64位系統上運行,microsoft提供了Windows 32-bit On Windows 64-bit的模擬層,又稱WOW64。IsWow64Process函數
非統一內存訪問(Non-Uniform Memory Access)NUMA機器中的CPU既能訪問自己節點的內存,也能訪問其他節點的內存。
確定地址空間的狀態 VirtualQuery(Ex)
在Windows Vista上,如果啟動多次一個EXE,其加載的同一DLL的位置可能不同,這是windows vista的地址空間布局隨機化(Address Space Layout Randomization)ASLR.
?
widows提供了以下三種機制來對內存進行操控:
虛擬內存:最適合用來管理大型對象數組或大型結構數組
內存映射文件:最適合用來管理大型數據流(通常是文件),以及在同一機器上運行的多個進程之間共享數據
堆:最適合用來管理大量的小型對象
虛擬內存:最適合用來管理大型對象數組或大型結構數組
VirtualAlloc?MEM_RESERVE預訂? MEM_COMMIT調撥??? 基地址通常會被向下取整到頁面大小的整數倍,而大小則會被向上取整到頁面大小的整數倍。
VirtualFree?撤銷調撥
VirtulaProtect 改變頁面的保護屬性
地址窗口擴展Address Windowing Extension(AWE):1.系統不會把以這種方式分配的內存換出到磁盤上;2.允許應用程序訪問比進程地址空間還要多的內存。
系統默認會預訂1MB的地址空間并調撥兩個頁面的存儲器,?/STACK 指定的值寫入PE文件頭
_beginthreadex中的參數優先于上面的值
棧頂棧低都有保護區間
內存映射文件 (windows許多方法用此來在進程間傳送數據)
?
#include <Windows.h>#pragma data_seg("MySec") volatile LONG g_lApplicationInstances = 0; //要初始化,否則會放入.bss未初始化數據段,如不初始化要用allocate #pragma data_seg()#pragma comment(linker, "/Section:MySec,RWS") //R READ W WRITE S SHARED #pragma comment(linker, "/subsystem:\"windows\" /entry:\"wmainCRTStartup\"") //關閉CMD窗口void wmain() {InterlockedExchangeAdd(&g_lApplicationInstances, 1);int bRet = 0;do{wchar_t buf[3] = { '\0' };_itow_s(g_lApplicationInstances,buf,3,10);bRet = MessageBoxW(NULL,buf,NULL,MB_YESNO);}while(bRet == IDYES );InterlockedExchangeAdd(&g_lApplicationInstances, -1); }
?
總結
以上是生活随笔為你收集整理的内存体系 用共享段于进程间联系的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 线程池之工作项,等待项,计时项 (存在疑
- 下一篇: 内存映射文件