Microsoft Windows 提供了三种机制来对内存进行操作。
1、堆-----------最适合用来管理大量的小型对象。
2、虚拟内存-----最适合用来管理大型对象数组或大型结构数组。
LPVOID VirtualAlloc(
LPVOID lpAddress, // 要分配的内存区域的地址
DWORD dwSize, // 分配的大小
DWORD flAllocationType, // 分配的类型
DWORD flProtect // 该内存的初始保护属性
);
功能:在调用进程的虚地址空间中,预定或者提交一部分页。
LPVOID lpAddress, 分配内存区域的地址。当你使用VirtualAlloc来提交一块以前保留的内存块的时候,lpAddress参数可以用来识别以前保留的内存块。如果这个参数是NULL,系统将会决定分配内存区域的位置,并且按64-KB向上取整(roundup)。
SIZE_T dwSize, 要分配或者保留的区域的大小。这个参数以字节为单位,而不是页,系统会根据这个大小一直分配到下页的边界DWORD
flAllocationType, 分配类型。MEM_RESERVE预定地址空间区域;MEM_COMMIT调拨物理存储器,即真正的分配内存。也可预定与分配同时进行。
DWORD flProtect 指定了被分配区域的访问保护方式
SIZE_T WINAPI VirtualQuery(
_In_opt_ LPCVOID lpAddress, //address of the region of pages to be queried.
_Out_ PMEMORY_BASIC_INFORMATION lpBuffer, //address of information buffer
_In_ SIZE_T dwLength //size of buffer
);
功能:查看进程内存地址空间的页面分配情况。
BOOL VirtualFree(
LPVOID lpAddress, // 区域地址
SIZE_T dwSize, // 区域大小,字节
DWORD dwFreeType // 类型
);
1、堆-----------最适合用来管理大量的小型对象。
2、虚拟内存-----最适合用来管理大型对象数组或大型结构数组。
3、内存映射文件-最适合用来管理大型数据流(通常是文件),以及在同一机器上运行的多个进程之间共享数据。
LPVOID VirtualAlloc(
LPVOID lpAddress, // 要分配的内存区域的地址
DWORD dwSize, // 分配的大小
DWORD flAllocationType, // 分配的类型
DWORD flProtect // 该内存的初始保护属性
);
功能:在调用进程的虚地址空间中,预定或者提交一部分页。
LPVOID lpAddress, 分配内存区域的地址。当你使用VirtualAlloc来提交一块以前保留的内存块的时候,lpAddress参数可以用来识别以前保留的内存块。如果这个参数是NULL,系统将会决定分配内存区域的位置,并且按64-KB向上取整(roundup)。
SIZE_T dwSize, 要分配或者保留的区域的大小。这个参数以字节为单位,而不是页,系统会根据这个大小一直分配到下页的边界DWORD
flAllocationType, 分配类型。MEM_RESERVE预定地址空间区域;MEM_COMMIT调拨物理存储器,即真正的分配内存。也可预定与分配同时进行。
DWORD flProtect 指定了被分配区域的访问保护方式
SIZE_T WINAPI VirtualQuery(
_In_opt_ LPCVOID lpAddress, //address of the region of pages to be queried.
_Out_ PMEMORY_BASIC_INFORMATION lpBuffer, //address of information buffer
_In_ SIZE_T dwLength //size of buffer
);
功能:查看进程内存地址空间的页面分配情况。
BOOL VirtualFree(
LPVOID lpAddress, // 区域地址
SIZE_T dwSize, // 区域大小,字节
DWORD dwFreeType // 类型
);
功能:取消或者释放调用进程的虚地址空间页的一个区域。
下面是一个简单的事例程序
#include <Windows.h>
#include <tchar.h>
#include <iostream>
//转载请注明文章来自:http://blog.youkuaiyun.com/windows_nt
typedef TCHAR *PTSTR;
void main()
{
TCHAR szAppName[] = _T("MEM_RESET tester");
TCHAR szTestData[] = _T("Some text data");
// Commit a page of storage and modify its contents.
PTSTR pszData = (PTSTR) VirtualAlloc(NULL, 1024,
MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
lstrcpy(pszData, szTestData);
{
printf(_T("Modified data page.\n"));
// We want this page of storage to remain in our process but the
// contents aren't important to us anymore.
// Tell the system that the data is not modified.
// Note: Because MEM_RESET destroys data, VirtualAlloc rounds
// the base address and size parameters to their safest range.
// Here is an example:
// VirtualAlloc(pvData, 5000, MEM_RESET, PAGE_READWRITE)
// resets 0 pages on CPUs where the page size is greater than 4 KB
// and resets 1 page on CPUs with a 4 KB page. So that our call to
// VirtualAlloc to reset memory below always succeeds, VirtualQuery
// is called first to get the exact region size.
MEMORY_BASIC_INFORMATION mbi;
VirtualQuery(pszData, &mbi, sizeof(mbi));
VirtualAlloc(pszData, mbi.RegionSize, MEM_RESET, PAGE_READWRITE);
}
{
printf(_T("clear data page.\n"));
// Commit as much storage as there is physical RAM.
MEMORYSTATUS mst;
GlobalMemoryStatus(&mst);
PVOID pvDummy = VirtualAlloc(NULL, mst.dwTotalPhys,
MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
// Touch all the pages in the dummy region so that any
// modified pages in RAM are written to the paging file.
ZeroMemory(pvDummy, mst.dwTotalPhys);
}
}