zoukankan      html  css  js  c++  java
  • Windows编程--虚拟内存基础

     系统信息

     许多操作系统的值是根据主机而定的,比如页面的大小分配粒度的大小等。这些值决不应该用硬编码的形式放入你的源代码。相反,你始终都应该在进程初始化的时候检索这些值,并在你的源代码中使用检索到的值。GetSystemInfo函数将用于检索与主机相关的值

     

    VOID GetSystemInfo(LPSYSTEM_INFO psinf);


     

    SYSTEM_INFO数据结构的样子。

    typedef struct _SYSTEM_INFO

    {

    union

    {

    DWORD dwOemId;
    //Obsolete, do not use

    struct

    {

    WORD wProcessorArchitecture;

    WORD wReserved;

    };

    };

    DWORD dwPageSize;

    LPVOID lpMinimumApplicationAddress;

    LPVOID lpMaximumApplicationAddress;

    DWORD_PTR dwActiveProcessorMask;

    DWORD dwNumberOfProcessors;

    DWORD dwProcessorType;

    DWORD dwAllocationGranularity;

    WORD wProcessorLevel;

    WORD wProcessorRevision;

    } SYSTEM_INFO,
    *LPSYSTEM_INFO;

     

    与内存有关的成员函数(其它变可参看MSDN

    dwPageSize 用于显示CPU的页面大小。在x86 CPU上,这个值是4096字节。在Alpha CPU 上,这个值是8192字节。在IA-64上,这个值是8192字节

     lpMinimumApplicationAddress用于给出每个进程的可用地址空间的最小内存地址。在Windows 98上,这个值是4 194 304,或0x00400000,因为每个进程的地址空间中下面的4MB是不能使用的。在Windows 2000上,这个值是65 5360x00010000,因为每个进程的地址空间中开头的64KB总是空闲的

     lpMaximumApplicationAddress用于给出每个进程的可用地址空间的最大内存地址。在Windows 98 上,这个地址是2 147 483 6470x7FFFFFFF,因为共享内存映射文件区域和共享操作系统代码包含在上面的2GB分区中。在Windows 2000上,这个地址是内核方式内存开始的地址,它不足64KB

     dwAllocationGranularity 显示保留的地址空间区域的分配粒度

     

    虚拟内存的状态

    Windows函数GlobalMemoryStatus可用于检索关于当前内存状态的动态信息:

    VOID GlobalMemoryStatus(LPMEMORYSTATUS pmst);

    当调用GlobalMemoryStatus时,必须传递一个MEMORYSTATUS结构的地址。下面显示了MOMORYSTATUS的数据结构。

    typedef struct _MEMORYSTATUS
    {
    DWORD dwLength;
    DWORD dwMemoryLoad;
    SIZE_T dwTotalPhys;
    SIZE_T dwAvailPhys;
    SIZE_T dwTotalPageFile;
    SIZE_T dwAvailPageFile;
    SIZE_T dwTotalVirtual;
    SIZE_T dwAvailVirtual;
    } MEMORYSTATUS,
    *LPMEMORYSTATUS;

     在调用GlobalMemoryStatus之前,必须将dwLength成员初始化为用字节表示的结构的大小,即一个MEMORYSTATUS结构的大小。

     

    如果希望应用程序在内存大于4GB的计算机上运行,或者合计交换文件的大小大于4GB,那么可以使用新的GlobalMemoryStatusEx函数:

    MEMORYSTATUSEX结构的地址:

    BOOL GlobalMemoryStatusEx(LPMEMORYSTATUSEX pmst);

     

    必须给该函数传递新的

    typedef struct _MEMORYSTATUSEX

    {

    DWORD dwLength;

    DWORD dwMemoryLoad;

    DWORDLONG ullTotalPhys;

    DWORDLONG ullAvailPhys;

    DWORDLONG ullTotalPageFile;

    DWORDLONG ullAvailPageFile;

    DWORDLONG ullTotalVirtual;

    DWORDLONG ullAvailVirtual;

    DWORDLONG ullAvailExtendedVirtual;

    } MEMORYSTATUSEX,
    *LPMEMORYSTATUSEX;

     

    这个结构与原先的MEMORYSTATUS结构基本相同,差别在于新结构的所有成员的大小都是6 4位宽,因此它的值可以大于4GB。最后一个成员是ullAv ailExtendedVirtual,用于指明在调用进程的虚拟地址空间的极大内存(VLM)部分中未保留内存的大小。该VLM部分只适用于某些配置中的某些CPU结构。 

     确定地址空间的状态

     Windows提供了一个函数,可以用来查询地址空间中内存地址的某些信息(如大小,存储器类型和保护属性等)。

    这个函数称为VirtualQuery

    DWORD VirtualQuery(

    LPCVOID pvAddress,

    PMEMORY_BASIC_INFORMATION pmbi,

    DWORD dwLength);

     

    Windows还提供了另一个函数,它使一个进程能够查询另一个进程的内存信息

    DWORD VirtualQueryEx(

    HANDLE hProcess,

    LPCVOID pvAddress,

    PMEMORY_BASIC_INFORMATION pmbi,

    DWORD dwLength);

     

    这两个函数基本相同,差别在于使用VirtualQueryEx时,可以传递你想要查询的地址空间信息的进程的句柄。调试程序和其他实用程序使用这个函数最多,几乎所有的应用程序都只需要调用VirtualQuery函数。

    当调用VirtualQueryEx)函数时,

    pvAddress参数必须包含你想要查询其信息的虚拟内存地址。

    Pmbi参数是你必须分配的MEMORY_BASIC_INFORMATION结构的地址。该结构在WinNT.h文件中定义为下面的形式:

    typedef struct _MEMORY_BASIC_INFORMATION

    {

    PVOID BaseAddress;

    PVOID AllocationBase;

    DWORD AllocationProtect;

    SIZE_T RegionSize;

    DWORD State;

    DWORD Protect;

    DWORD Type;

    } MEMORY_BASIC_INFORMATION,
    *PMEMORY_BASIC_INFORMATION;


    最后一个参数是dwLength用于设定MEMORY_BASIC_INFORMATION结构的大小。VirtualQueryEx)函数返回拷贝到缓存中的字节的数量。

     

     FangSH  19:08 2011-1-6

       

  • 相关阅读:
    用户模式同步之互斥体小解
    用户模式同步之信号量小解
    用户模式同步之事件小解
    中断和异常
    断点之软件断点的一些基本知识(INT3)
    部署Django项目Nginx + uwsgi
    CentOS切换root用户一直提示Incorrect password
    一张图看懂Mysql的join连接
    Nginx部署入门
    Django使用多个数据库
  • 原文地址:https://www.cnblogs.com/fangshenghui/p/1929070.html
Copyright © 2011-2022 走看看