一:内存管理基础
1:win32中的内存管理是分层次的,系统提供了几组层次不同的函数来管理内存
分别是:标准内存管理函数、堆管理函数、虚拟内存管理函数 和内存映射文件函数.
2:标准内存管理函数,总是在默认堆中分配和释放内存,这组函数就是常规意义上的内存管理函数
3:堆管理函数相对比较高级一点,堆的主要功能就是有效的管理内存和进程的地址空间。DOS操作系统下的C语言中就已经有了“堆”的概念,这时的堆是程序初始化的时候向操作系统申请并预留的大块内存,程序通过C函数在这块内存中申请和释放内存,
在win32中,进程可以使用的整个地址空间就是一个堆。并且“堆”的概念又被引申了一部:win32分两种堆,一种是进程的“默认堆”,默认堆只有一个,指的就是可以使用的整个地址空间;另一种是“动态堆”,也称为“私有堆”,私有堆类似于DOS下C语言中使用的那种堆,一个进程可以随意建立多个私有堆,也可以随意将它们释放,私有堆全部位于默认堆中,从概念上看,它和默认堆并没有什么不同,就像一个跨国公司和属下的子公司同样都是按照公司的规程操作一样。使用堆管理函数可以对所有的私有堆和默认堆进行操作
3:虚拟内存管理函数 来管理虚拟内存,主要用于保留、提交、释放虚拟内存,在虚拟内存也上改变保护方式、锁定虚拟内存也,以及查询一个进程的虚拟内存等操作,这是一组位于底层的函数
4:内存映射文件函数相对比较独立,它是为了文件操作的方便性而设立的,当对文件进行操作的时候,一般总是先打开文件,然后申请一块内存用作缓冲区,再将文件数据循环读入并处理,当文件长度大于缓冲区长度的时候需要多次读入,每次读入后处理缓冲区边界位置的数据往往是个麻烦的问题,曾经介绍过windows可以使用磁盘文件当作虚拟内存,内存映射文件函数就是使用同样的办法将一个文件直接映射到进程的地址空间中的,这样可以通过内存指针用读写内存的办法直接存取文件内容。
二:内存的当前状态
1:在设计一个可能需要申请大量内存的程序的时候,如何预先得知系统的配置情况呢?
一般使用函数GlobalMemoryStatus(lpbuffer)
lpbuffer 指向一个MEMORYSTATUS结构
在调用之前需要将dwlength字段设置为MEMORYSTATUS结构的长度,
三:标准内存管理函数
1: 固定的内存块
//----------------------申请--------------------------------
GlobalAlloc(GMEM_FIXED|GMEM_ZEROINIT , dwBytes)
//(GMEM_FIXED :表示要申请的是固定的内存块,GMEM_ZEROINIT:表示需要将内存块中的所有字节预先初始化为0,可以用GRTY标志替代两个的组合
//dwBytes 指出需要申请的以字节为单位的内存大小
//内存申请失败,函数返回NULL
//内存申请成功,函数返回一个指向内存块起始地址的指针
//---------------------释放--------------------------------
GbolalFree(lpMemory)
//释放成功,返回NULL,否则返回输入的lpMemory
2: 可移动的内存块
GlobalAlloc(GMEM_MOVEABLE|GMEM_ZEROINIT , dwBytes)
要使用可移动的内存之前,需要将它锁定,这是告诉windows现在的程序要使用这块内存了,不能将它移动,
GlobalLock(hMemory)
当程序不需要操作这个内存的时候,应该将它解锁,GlobalUnlock(hMemory)
这里有个问题:如果两个线程在同一块内存中进行操作,在其中一个进行操作的时候,另一个线程却解锁了,这个时候怎么办?
这个问题不用担心,windows为每个可移动的内存句柄维护一个锁定技术,每次锁定内存的时候计数加1,解锁的时候计数减1,只有当计数为0的时候内存才真正的被解锁,只要加锁和解锁的函数是配对的就不会有问题
释放可移动的内存快:GlobalFree(hMempry)
3: 可丢弃的内存快
GlobalAlloc(GHND|GMEM_DISCARDABLE,dwBytes)
返回NULL的时候,表示内存被windows丢弃了
未完,待续……