对内存的管理
使用虚拟内存技术将能够对内存进行管理。对当前内存状态的动态信息可通过GlobalMemoryStatus()函数来获取。GlobalMemoryStatus()的函数原型为:
VOID GlobalMemoryStatus(LPMEMORYSTATUS lpBuffer);
其参数lpBuffer为一个指向内存状态结构MEMORYSTATUS的指针,而且要预先对该结构对象的数据成员进行初始化。MEMORYSTATUS结构定义如下:
typedef struct _MEMORYSTATUS { DWORD dwLength; // MEMORYSTATUS结构大小 DWORD dwMemoryLoad; // 已使用内存所占的百分比 DWORD dwTotalPhys; // 物理存储器的总字节数 DWORD dwAvailPhys; // 空闲物理存储器的字节数 DWORD dwTotalPageFile; // 页文件包含的最大字节数 DWORD dwAvailPageFile; // 页文件可用字节数 DWORD dwTotalVirtual; // 用户模式分区大小 DWORD dwAvailVirtual; // 用户模式分区中空闲内存大小 } MEMORYSTATUS, *LPMEMORYSTATUS; 下面这段代码通过设置一个定时器而每隔5秒更新一次当前系统对内存的使用情况: // 设置定时器 SetTimer(0, 5000, NULL); …… void CSample22Dlg::OnTimer(UINT nIDEvent) { // 获取当前内存使用状态 MEMORYSTATUS mst; GlobalMemoryStatus(&mst); // 已使用内存所占的百分比 m_dwMemoryLoad = mst.dwMemoryLoad; // 物理存储器的总字节数 m_dwAvailPhys = mst.dwAvailPhys / 1024; // 空闲物理存储器的字节数 m_dwAvailPageFile = mst.dwAvailPageFile / 1024; // 页文件包含的最大字节数 m_dwAvailVirtual = mst.dwAvailVirtual / 1024; // 页文件可用字节数 m_dwTotalPageFile = mst.dwTotalPageFile / 1024; // 用户模式分区大小 m_dwTotalPhys = mst.dwTotalPhys / 1024; // 用户模式分区中空闲内存大小 m_dwTotalVirtual = mst.dwTotalVirtual / 1024; // 更新显示 UpdateData(FALSE); CDialog::OnTimer(nIDEvent); } |
对内存的管理除了对当前内存的使用状态信息进行获取外,还经常需要获取有关进程的虚拟地址空间的状态信息。可由VirtualQuery()函数来进行查询,其原型声明如下:
DWORD VirtualQuery( LPCVOID lpAddress, // 内存地址 PMEMORY_BASIC_INFORMATION lpBuffer, // 指向内存信息结构的指针 DWORD dwLength // 内存的大小 ); |
其中lpAddress参数为要查询的虚拟内存地址,该值将被调整到最近的页边界处。当前计算机的页面大小可通过GetSystemInfo()函数获取,该函数需要一个指向SYSTEM_INFO结构的指针作为参数,获取到的系统信息将填充在该数据结构对象中。下面这段代码通过对GetSystemInfo()的调用而获取了当前的系统信息:
// 得到当前系统信息 GetSystemInfo(&m_sin); // 位屏蔽,指明哪个CPU是活动的 m_dwActiveProcessorMask = m_sin.dwActiveProcessorMask; // 保留的地址空间区域的分配粒度 m_dwAllocationGranularity = m_sin.dwAllocationGranularity; // 进程的可用地址空间的最小内存地址 m_dwMaxApplicationAddress = (DWORD)m_sin.lpMaximumApplicationAddress; // 进程的可用地址空间的最大内存地址 m_dwMinApplicationAddress = (DWORD)m_sin.lpMinimumApplicationAddress; // 计算机中CPU的数目 m_dwNumberOfProcessors = m_sin.dwNumberOfProcessors; // 页面大小 m_dwPageSize = m_sin.dwPageSize; // 处理器类型 m_dwProcessorType = m_sin.dwProcessorType; //进一步细分处理器级别 m_wProcessorLevel = m_sin.wProcessorLevel; // 系统处理器的结构 m_wProcessorArchitecture = m_sin.wProcessorArchitecture; // 更新显示 UpdateData(FALSE); VirtualQuery()的第二个参数lpBuffer为一个指向MEMORY_BASIC_INFORMATION结构的指针。VirtualQuery()如成功执行,该结构对象中将保存查询到的虚拟地址空间状态信息。MEMORY_BASIC_INFORMATION结构的定义为: typedef struct _MEMORY_BASIC_INFORMATION { PVOID BaseAddress; // 保留区域的基地址 PVOID AllocationBase; // 分配的基地址 DWORD AllocationProtect; // 初次保留时所设置的保护属性 DWORD RegionSize; // 区域大小 DWORD State; // 状态(提交、保留或空闲) DWORD Protect; // 当前访问保护属性 DWORD Type; // 页面类型 } MEMORY_BASIC_INFORMATION; |
通过VirtualQuery()函数对由lpAddress和dwLength参数指定的虚拟地址空间区域的查询而获取得到的相关状态信息:
// 更新显示 UpdateData(TRUE); // 虚拟地址空间状态结构 MEMORY_BASIC_INFORMATION mbi; // 查询指定虚拟地址空间的状态信息 VirtualQuery((LPCVOID)m_dwAddress, &mbi, 1024); // 保留区域的基地址 m_dwBaseAddress = (DWORD)mbi.BaseAddress; // 分配的基地址 m_dwAllocateBase = (DWORD)mbi.AllocationBase; // 初次保留时所设置的保护属性 m_dwAllocateProtect = mbi.AllocationProtect; // 区域大小 m_dwRegionSize = mbi.RegionSize; // 状态(提交、保留或空闲) m_dwState = mbi.State; // 当前访问保护属性 m_dwProtect = mbi.Protect; // 页面类型 m_dwType = mbi.Type; // 更新显示 UpdateData(FALSE); |
小结
本文主要对内存管理中的虚拟内存技术的基本原理、使用方法和对内存的管理等进行了介绍。通过本文将能够掌握虚拟内存的一般使用方法,与之相关的内存管理技术还包括内存文件映射和堆管理等技术,读者可参阅相关文章。这几种内存管理技术同属Windows编程(www.cppentry.com)中的高级技术,在应用程序中适当使用将有助于程序性能的提高。本文所述程序在Windows 2000 Professional下由Microsoft Viusual C++(www.cppentry.com) 6.0编译通过。
|