内存管理API

来源:互联网 发布:王石田朴珺 知乎 编辑:程序博客网 时间:2024/06/06 04:15

一、进程的内存空间

1、实现

  为实现系统中每个进程都有一个私有的虚拟地址空间,系统为每个进程都创建了一个页目录和一组页表。每个进程的页表是独立的,而内核空间中的页表是共享的。

  x86平台上,CR3寄存器标识了页目录所在的物理地址。Windows系统上的第一个进程都有独立的页目录,因此系统运行时,CR3寄存器中保存的页目录地址是会变化的,其值为当前运行的进程的页目录地址。当系统要进行进程切换时,会将CR3设置成新进程的页目录地址。          Windows平台的每一个进程都有一个KPROCESS结构的数据块,其中包括了其进程页目录的地址。

 

2、数据共享与保护

  不同进程的虚拟内存分页可以映射为相同的物理内存分页。

  同时,为了保证这种在映射到相同物理内存分页上的内存分页在进程上仍然是私有的,系统还提供了一些保护机制。如果将某个系统DLL加载到进程内存空间以后,对该DLL中的数据进行了写操作,系统就会监视到该操作,并在数据写入之前将要写入的进程虚拟内存分页映射到另一个新的物理分页,并将原分页中系统DLL的内容复制到这个分页中,进程间不共享这个新物理内存分页,最后进程完成写操作,将数据写入到这个新分页中。这种对内存中系统DLL数据的写入操作不会影响到其他进程,因此保护了各个进程中数据的独立性,这种机制叫做Copy-On-Write。如果进程间确实要共享数据,可以对特定的页面不使用该机制。

 


 二、内存页面的保护属性和存取权限

 

 

保护属性与存储权限

属性常量

意义

PAGE_EXECUTE

可执行

PAGE_EXECUTE_READ

可读、可执行

PAGE_EXECUTE_READWRITE

可读、可写、可执行

PAGE_EXECUTE_WRITECOPY

可读、可写、可执行,以Read-On-WriteCopy-On-Write方式共享

PAGE_NOACCESS

不可访问

PAGE_READONLY

只读

PAGE_READWRITE

可读可写

PAGE_WRITECOPY

Copy-On-Write保护机制

PAGE_GUARD

保护,如果访问则产生异常(不能单独使用)

PAGE_NOCHANGE

不进行CPU缓存(不能单独使用)

PAGE_WRITECOMBINE

Write-Combined优化(不能单独使用)

 


三、内存管理API

 

堆管理API函数

API

功能简介

HeapCreate

为进程创建一个堆,返回堆句柄

GetProcessHeap

获取当前进程中的一个堆,返回一个句柄

GetProcessHeaps

获得进程中所有堆,包括堆的数量和各个堆的句柄

HeapAlloc

从指定堆上分配内存块

HeapReAlloc

重新分配内存,改变已经分配好的的堆内存块大小

GetSystemInfo

获取系统信息

HeapSize

获取指定堆的大小,以字节为单位返回堆的大小信息

HeapFree

释放从堆中分配的内存

HeapDestroy

销毁堆

 

 

 

全局和局部内存管理API函数

API

功能简介

GlobalAlloc

在默认堆上分配指定属性和大小的内存

GlobalFree

释放由GlobalAlloc分配的内存

GlobalReAlloc

重新分配内存,改变已经分配好的堆内存块的大小

GlobalLock

GlobalAllocGlobalReAlloc分配的属性为GMEM_MOVEABLE的内存块设为固定

GlobalHandle

GlobalLock相对

GlobalSize

获取内存大小

 

 

 

 

虚拟内存管理API函数

API

功能简介

VirtualAlloc

申请虚拟内存,将“空闲的”页面变为“保留”或“已提交的”,将“保留的”页面编程“已提交的”

VirtualAllocEx

类似VirtualAlloc,还可以为其他进程分配内存

VirtualFree

将内存状态从“已提交的”变为“保留的”,或将“保留的”变为“空闲的”,或同时进行

VirtualFreeEx

释放由VirtualAllocEx分配的内存

VirtualProtect

改变指定虚拟内存分页的保护属性

 

 

 

内存操作与内存信息管理API函数

API

功能简介

CopyMemory

复制内存

FillMemory

填充内存

MoveMemory

功能和CopyMemory相同,源内存块和目的内存块可以重叠

ZeroMemory

将指定内存区域初始化为0

GlobalMemoryStatusEx

获取系统当前内存使用情况

IsBadCodePtr

判断调用进程是否拥有对指定地址的读操作权限

IsBadReadPtr

判断调用进程是否拥有对指定地址段的读操作权限

IsBadStringPtr

判断调用进程是否拥有对指定字符串指针的读取权限

IsBadWritePtr

判断调用进程是否拥有对指定地址段的写操作权限

 

 

 

  HeapAlloc、GlobalAlloc、LocalAlloc在功能上没有大的区别,都是在堆中分配内存,分配的内存不需要进行页对齐,也不用关心分页机制、页面状态、页面属性等内容。HeapAlloc是程序在需要分配内存时最直接的方式。GlobalAlloc、LocalAlloc需要兼容16位系统,所需进行的判断和处理会更多,因此二者性能较HeapAlloc稍低。

  堆内存管理依赖于虚拟内存管理。在创建堆时,HeapCreate函数会向系统请求虚拟内存分页,之后在这个堆上的内存分配实际上是从虚拟内存管理中获取的内存分页上再分配大小任意的内存块,如果建立堆时指定了堆大小,那么在堆上分配内存时,其范围不能超过设置的堆大小,堆大小一定是内存页大小的整数倍。如果在建立堆时不固定堆的大小,堆管理函数会根据分配的请求数量动态地向虚拟内存管理函数请求内存分页。

  VirtualAlloc的功能是对进程虚拟地址空间中内存分页的状态进行管理,属于虚拟内存管理的范围。

  C的内存分配函数直接使用了HeapAlloc。

原创粉丝点击