windows内存

Windows内存地址空间
  1. 地址空间
    程序中可以寻址的最大范围。对于32位操作系统,
    地址空间范围为0-4G(2^32),地址空间越大,
    相对程序的编写就会容易。
  2. 地址空间的划分
    • 用户地址空间 0 - 2G(7FFFFFFF )
      存放用户的程序和数据。
      用户空间的代码是不能访问内核空间的数据和代码。
      • 空指针区(NULL区,0-64K)系统将地址小于64K指针,都认为是空指针。
      • 用户区
      • 64K禁入区(0x7FFEFFFF - 0x7FFFFFFF )
    • 内核地址空间 2G - 4G
      存放内核的代码和数据,例如系统驱动。
      内核空间代码是可以访问用户空间。
windows内存
  1. 区域
    区域就是连续的一块内存。区域的大小一般为64K或者64K倍数。每个区域都有自己的状态:
    • 空闲:没有被使用
    • 私有:被预定的区域
    • 映像:存放代码
    • 映射:存放数据
  2. 物理内存
    系统可以使用的实际内存。CPU可以直接访问的内存。
  3. 虚拟内存(硬盘交换文件)
    将硬盘文件虚拟成内存使用。(pagefile.sys 文件)
    CPU如果要访问虚拟内存数据,必须将虚拟内存数据
    放到物理内存。

  4. 内存页
    系统管理地址的最小单位。内存页大小为4K,每个
    内存页有自己的权限。
  5. 页目表
    指针地址
    31 22 21 12 11 0
    |-----------|------------|--------------|
    10位 10位 12位

     2^10=1024       1024           4K
      页目                  页表         页内偏移地址
  6. 从内存获取数据过程
    • 根据地址在物理内存中查找相应的位置。如果找到物理内存,取回数据。如果未找到,执行下一步.
    • 根据地址去虚拟内存中查找相应的位置。如果未找到,那么该地址没有内存空间,返回错误。如果找到,执行下一步.
    • 将该地址所在内存页,置换到物理内存中,同时将原物理内存数据,存入到虚拟内存中。
    • 将物理内存中的数据返回给使用者。
  7. 内存分配
    • 虚拟内存分配-适合大内存分配,一般是1M之上的内存。
    • 堆内存分配-适合小内存分配,一般是1M以下的内存。
      malloc/new
    • 栈内存分配-适合小内存分配,一般是1M以下的内存。
虚拟内存分配
  1. 虚拟内存分配
    速度快,大内存效率高。将内存和地址分配分别执行,可以在需要的时候再提交内存。常用字大型电子表格等处理。
  2. 虚拟内存使用
    • 内存分配
        LPVOID VirtualAlloc(
            LPVOID lpAddress,// NULL或提交地址
            SIZE_T dwSize, //分配的大小
            DWORD flAllocationType, //分配方式
            DWORD flProtect //内存访问方式
        );    分配成功返回地址
    • 分配方式:
      MEM_COMMIT - 提交内存,分配之后返回地址和内存空间
      MEM_RESERVE- 保留地址,分配之后只返回地址,内存空间不生成。要使用内存必须再次提交。
  • 使用
  • 释放
    BOOL VirtualFree(
    LPVOID lpAddress,//释放地址
    SIZE_T dwSize, //释放的大小0
    DWORD dwFreeType //释放方式
    );
    * 释放方式:
    MEM_DECOMMIT - 只释放内存,不释放地址
    MEM_RELEASE - 地址和内存都释放
堆内存 Heap
  1. 堆内存分配
    适合分配小内存,一般是小于1M的内存。一般每个程序都有自己的堆,默认大小为1M,会根据使用情况进行调整。
  2. 堆的使用
    • 堆的信息
      GetProcessHeap - 获得程序的第一个堆
      GetProcessHeaps - 获取程序中所有的堆
    • 创建堆
            HANDLE HeapCreate(
                DWORD flOptions,//创建选项
                 SIZE_T dwInitialSize, //初始化大小1024*1024
                 SIZE_T dwMaximumSize //最大值0
            ); 成功返回堆句柄
    • 从堆中分配内存(获取堆中内存的地址)
      LPVOID HeapAlloc(
      HANDLE hHeap, //堆句柄
      DWORD dwFlags, //分配方式
      SIZE_T dwBytes //分配大小210241024
      ); 成功返回地址
    • 使用内存
    • 释放内存
      BOOL HeapFree(
      HANDLE hHeap, // 堆句柄
      DWORD dwFlags, // 释放方式
      LPVOID lpMem // 释放地址
      );

    • 销毁堆
      BOOL HeapDestroy(
      HANDLE hHeap //堆句柄
      );
      当堆被销毁后,使用该堆分配内存全都被销毁。
  3. VirtualAlloc/HeapAlloc/malloc/new在Windows平台上,函数调用关系:
    new/malloc -> HeapAlloc。。。。。
栈内存

栈内存-每个线程都具有自己的栈,默认大小1M。
一般是系统维护栈。
Windows提供了 _alloca, 可以在栈上分配内存。

  • 内存映射文件
    将文件映射成内存来使用。当使用内存时,就是在使用文件。
    内存映射文件的使用
    1. 创建或打开文件CreateFile
    2. 创建内存映射文件
    HANDLE CreateFileMapping(
        HANDLE hFile, //文件句柄
        LPSECURITY_ATTRIBUTES lpAttributes, //安全属性
        DWORD flProtect,//访问方式
        DWORD dwMaximumSizeHigh,//内存映射文件大小的高32
        DWORD dwMaximumSizeLow, //内存映射文件大小的低32
         LPCTSTR lpName //命名,可以为NULL
    );    创建成功返回句柄
    1. 获取内存映射文件某个地址
    LPVOID MapViewOfFile(
        HANDLE hFileMappingObject,//内存映射文件句柄
        DWORD dwDesiredAccess,       //访问模式
        DWORD dwFileOffsetHigh,  //偏移量的高32位
        DWORD dwFileOffsetLow,       //偏移量的低32位
        SIZE_T dwNumberOfBytesToMap  //不使用
         //映射的字节数量
    ); 成功返回地址
      dwFileOffsetHigh和dwFileOffsetLow合成的偏移量,必须是区域粒度的整数倍(64K的整数倍)
  1. 使用内存
  2. 将 地址 和 内存映射文件的 某个部分分开
    BOOL UnmapViewOfFile(
    LPCVOID lpBaseAddress //卸载地址
    );
  3. 关闭内存映射文件
    CloseHandle – 一旦关闭,就没了
  4. 关闭文件
    CloseHandle

转载于:https://www.cnblogs.com/lhfen/p/6040492.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值