内存体系 用共享段于进程间联系

本文深入探讨了Windows操作系统中的内存管理机制,包括虚拟地址空间的分区、内存映射文件的使用、地址空间布局随机化(ASLR)等特性,以及如何通过系统API进行内存的预订、调拨与释放。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

内存体系结构
虚拟地址分区:空指针赋值分区,用户模式分区,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);
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值