在Win32中管理虚拟内存
Randy Kath
Microsoft Developer Network 技术小组
创建于:1993年1月20日
单击此处以打开或复制 ProcessWalker 示例程序中的文件。该Win32 示例程序要求Microsoft Windows NT 的环境。
摘要
在Microsoft Windows NT 操作系统中,假如您对每组函数的功能,以及它们每个函数的作用,没有足够的认识,那么在Win32 应用程序中,决定使用哪个函数,或者哪组函数来管理内存将是困难的。为了简化这个问题,本篇技术文章主要是围绕Win32虚拟内存管理函数的:它包括哪些函数是可用的、如何使用它们,以及使用它们会对操作系统产生什么影响。本文将讨论如下的主题:
- 保留、提交,和释放虚拟内存
- 在虚拟内存页上改变保护
- 锁定虚拟内存页
- 查询一个进程的虚拟内存
在Microsoft Developer Network CD中有一个叫作ProcessWalker的示例程序,它将会在本篇技术文章中出现。该示例程序对于探索一个进程的内存地址空间是很有用的。它还使用了虚拟内存函数来实现一个相互链接的列表结构。
概述
本文是三篇相关技术文章中的其中一篇,这三篇文章分别是棗“在Win32中管理虚拟内存”、“在Win32中管理内存-映射文件”,以及快要完成的“在Win32中管理堆(heap)内存”棗它们解释了如何在Win32编程接口的应用程序中管理内存。在每篇文章的概述部分,要指明Win32编程模型中基本的内存部件,并且指出如果您对特殊领域的较有兴趣,那么应该参考哪一篇文章。
Microsoft Windows 操作系统的第一个版本介绍了基于一个单个的全局堆(global heap)和多个专有的局部堆(local heaps)来管理动态内存的方法,所有应用程序和系统共存该全局堆(global heap),而每一个应用程序具有其单独的局部堆(local heaps)。同时还提供了全局和局部的内存管理函数,为这种新的内存管理系统提供了扩展的特性。最近,Microsoft C的运行时(CRT)库被修改以包含如下功能,即使用如malloc和free这样的纯粹的CRT函数来管理Windows中的堆。所以,现在开发者应该作出选择了棗要么学习作为Windows 3.1版本的一部分来提供的新的应用程序编程接口(API),要么坚持使用可移植的、典型的、并且为人所熟悉的CRT函数在为Windows 3.1所编写的应用程序中管理内存。
随着Win32 API内容的不断增加,选择机会也随之增加。Win32提供了三个附加的函数组来管理应用程序的内存:内存-映射(memory-mapped)文件函数、堆内存(heap memory)函数,以及虚拟内存函数。这些新的函数并不替代在Windows 3.1中现存的内存管理函数;相反它们提供了新的特性,使得开发者在为他们的Win32应用程序编写内存管理部分时,日子会轻松得多。
图1. Win32 API为应用程序编程的多样性提供了不同级别的内存管理。
总之,如图1所看到的,在Win32中有六组内存管理函数,所有这些函数都被设计成单独使用。所以,您应该使用哪种函数呢?要回答这一问题主要依靠以下两件事:您希望的内存管理类型是什么,以及与之相关联的函数在操作系统中是如何实现的。换句话说,您是否是正在建立一个大的数据库应用程序,因而希望操作一个大的内存结构的子集合,或者您正计划一些简单的动态内存结构,例如链接列表或二进制树(binary trees)。在这两种情况下,您都需要搞清楚哪些函数提供的功能最适合您的意向,并确切地了解在使用每个函数时要占用多少资源。
表1将Win32中的内存管理函数组进行了分类,并且分别指出在本系列的三篇技术文章中,每一篇所描述的相关的组的行为。在每篇技术文章中,通过描述作为对使用这些函数的响应的系统行为,重点强调了这些函数对系统所产生的影响。
表1. 在Win32中可用的内存管理函数
内存设置 | 受影响的系统资源 | 相关的技术文章 |
虚拟内存函数 | 一个进程的虚拟地址空间 系统页文件 系统内存 硬盘空间 |
“在Win32中管理虚拟内存” |
内存-映射文件函数 | 一个进程的虚拟地址空间 系统页文件 标准文件I/O 系统内存 硬盘空间 |
“在Win32中管理内存-映射文件” |
堆(Heap)内存函数 |