实验目的
- 理解WINDOWS中堆、栈的内存布局
- 通过WNDOWS系统提供的系统调用HeapCreate(), HeapAlloc(), HeapFree()等函数的应用,理解虚拟内存管理技术中的内存分配原理。使用工具软件vmmap查看某个进程的虚拟地址空间,并理解虚地址空间中的相关术语。
- 通过WINDOWS提供的系统调用GetProcessMemoryInfo()理解操作系统原理书中所讲的相关内容。
实验内容
本实验要求用C语言书写一个用到以上系统调用的程序,要求对GetProcessMemoryInfo函数的返回内容理解并解释。
实验准备
相关理论知识
- 现代操作系统管理内存的基本原理,理解堆、栈等相关的内存术语。
- 了解工作集,缺页中断、页面等基本术语。
- 了解WINDOWS中管理内存的基本思想。
相关系统调用的解释
GetProcessMemoryInfo
BOOL WINAPI GetProcessMemoryInfo(_In_HANDLE Process,
_Out_PPROCESS_MEMORY_COUNTERS ppsmemCounters,
_In_DWORD cb);
该函数取一个进程的句柄为参数,返回该进程的内存使用信息。该函数的调用中,最重要的内容是对数据结构PROCESS_MEMORY_COUNTERS的解释。参见MSDN中,对该调用的解释和例子。
HeapAlloc
LPVOID WINAPI HeapAlloc(_In_HANDLE hHeap,_In_DWORD dwFlags, _In_SIZE_T dwBytes);
该函数取一个堆的句柄为参数,返回在dwBytes参数中设定的参数的内存大小。创建堆或获取堆的方法见MSDN。
实验过程
源代码
#include <stdlib.h>
#include <Windows.h>
#include <stdio.h>
#include <psapi.h>
void HeapInfo(HANDLE hHeap){
PROCESS_MEMORY_COUNTERS pmc;
if ( GetProcessMemoryInfo( hHeap, &pmc, sizeof(pmc)) )
{
printf( "\t页表错误数: 0x%08X\n", pmc.PageFaultCount );
printf( "\t峰值工作集大小: 0x%08X\n",
pmc.PeakWorkingSetSize );
printf( "\t工作集大小: 0x%08X\n", pmc.WorkingSetSize );
printf( "\t配额峰值分页池使用: 0x%08X\n",
pmc.QuotaPeakPagedPoolUsage );
printf( "\t配额分页池使用: 0x%08X\n",
pmc.QuotaPagedPoolUsage );
printf( "\t配额峰值未分页池使用: 0x%08X\n",
pmc.QuotaPeakNonPagedPoolUsage );
printf( "\t配额未分页池使用: 0x%08X\n",
pmc.QuotaNonPagedPoolUsage );
printf( "\t页面文件使用: 0x%08X\n", pmc.PagefileUsage );
printf( "\t峰值页面文件使用: 0x%08X\n",
pmc.PeakPagefileUsage );
}
}
int main()
{
//创建堆
HANDLE hHeap = HeapCreate(
HEAP_GENERATE_EXCEPTIONS,
1024 * 1024, 0 );
printf( "创建堆: %p\n",hHeap );
CHAR * pszBuf = (CHAR *)HeapAlloc( hHeap,HEAP_ZERO_MEMORY, 100 );
HeapInfo(hHeap);
//内存分配
printf( "堆分配: %p\n",pszBuf );
strcpy( pszBuf, "hello Heap");
printf( "%s\n", pszBuf );
//内存释放
HeapFree( hHeap, 0, pszBuf );
//释放堆
HeapDestroy( hHeap );
HeapInfo(hHeap);
CloseHandle( hHeap );
return 0;
}