科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基础软件虚拟内存技术原理和使用方法

虚拟内存技术原理和使用方法

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

本文主要对内存管理技术中的虚拟内存的基本原理和使用方法进行了介绍。

作者:中国电波传播研究所青岛分所郎锐 来源:yesky 2007年10月21日

关键字:

  • 评论
  • 分享微博
  • 分享邮件
对内存的管理

  使用虚拟内存技术将能够对内存进行管理。对当前内存状态的动态信息可通过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编程中的高级技术,在应用程序中适当使用将有助于程序性能的提高。本文所述程序在Windows 2000 Professional下由Microsoft Viusual C++ 6.0编译通过。

查看本文来源

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章