記憶體分配與跟蹤
編寫一個程式,包括兩個執行緒,一個執行緒用於模擬記憶體分配活動,另一個用於跟蹤第一個執行緒的記憶體行為,要求兩個執行緒之間通過訊號量實現同步,模擬記憶體活動的執行緒可以從一個檔案中讀出要進行的記憶體操作。每個記憶體操作包含如下內容:
時間:每個操作等待時間;
塊數:分配記憶體的粒度;
操作:包括保留一個區域、提交一個區域、釋放一個區域、回收一個區域、加鎖與解鎖一個區域。可將它們的編號放置於一個檔案中。
保留是指保留程序的虛地址空間,而不分配實體地址空間;
提交是指在記憶體中分配實體地址空間;
回收是指釋放實體地址空間,而保留程序的虛地址空間;
釋放是指將程序的實體地址與虛擬地址空間全部釋放;
大小:塊的大小;
訪問許可權:共五種PAGE_READONLY, PAGE_READWRIYE, PAGE_EXEXUTE, PAGE_EXEXUTE _READ, PAGE_EXEXUTE _READWRIYE.
#include <iostream>
#include <stdlib.h>
#include <windows.h>
#include "fstream"
using namespace std;
struct operation
{
int time;//起始時間
int block;//記憶體頁數
int oper;//操作
int protection;//許可權
};
struct trace
{
LPVOID start;//起始地址
long size;//分配的大小
};
HANDLE allo,trac;
DWORD Tracker(LPDWORD lpdwparm)//跟蹤執行緒的記憶體行為,並輸出必要資訊
{
ofstream outfile;
outfile.open("out.txt");
for(int i=0; i<=30; i++)
{
WaitForSingleObject(trac,INFINITE);//等待allocator一次記憶體分配活動結束
//列印記憶體狀況和系統狀況
outfile<<i<<endl;
SYSTEM_INFO info;//系統資訊
GetSystemInfo(&info);
outfile<<"頁面檔案大小"<<'\t'<<info.dwPageSize<<endl;
outfile<<"程序的最小記憶體地址"<<'\t'<<info.lpMinimumApplicationAddress<<endl;
outfile<<"程序的最大記憶體地址"<<'\t'<<info.lpMaximumApplicationAddress<<endl;
outfile<<"當前活動的CPU"<<'\t'<<info.dwActiveProcessorMask<<endl;
outfile<<"CPU的個數"<<'\t'<<info.dwNumberOfProcessors<<endl;
outfile<<"分配粒度"<<'\t'<<info.dwAllocationGranularity<<endl;
outfile<<"當前處理器結構圖"<<'\t'<<info.dwProcessorType<<endl;
outfile<<"_______________________________________________________"<<endl;
MEMORYSTATUS status;//記憶體狀態
GlobalMemoryStatus(&status);
outfile<<"MEMORYSTATUS結構的大小"<<'\t'<<status.dwLength<<endl; // sizeof(MEMORYSTATUS)
outfile<<"系統記憶體的使用率"<<'\t'<<status.dwMemoryLoad<<endl; // percent of memory in use
outfile<<"總的實體記憶體大小"<<'\t'<<status.dwTotalPhys<<endl; // bytes of physical memory
outfile<<"可用的實體記憶體大小"<<'\t'<<status.dwAvailPhys<<endl; // free physical memory bytes
outfile<<"顯示可以存在頁面檔案中的位元組數"<<'\t'<<status.dwTotalPageFile<<endl; // bytes of paging file
outfile<<"可用的頁面檔案大小"<<'\t'<<status.dwAvailPageFile<<endl; // free bytes of paging file
outfile<<"使用者模式的全部可用虛擬地址空間"<<'\t'<<status.dwTotalVirtual<<endl; // user bytes of address space
outfile<<"實際自由可用的虛擬地址空間"<<'\t'<<status.dwAvailVirtual<<endl; // free user bytes
outfile<<"__________________________________________________"<<endl;
//釋放訊號量通知allocator 可以執行下一次記憶體分配活動
ReleaseSemaphore(allo,1,NULL);
}
return 0;
}
void Allocator()//模擬記憶體分配活動的執行緒
{
trace traceArray[5];
int index=0;
FILE* file;
file=fopen("file","rb");//讀入檔案
operation op;
SYSTEM_INFO info;
DWORD temp;
GetSystemInfo(&info);
for(int i=0; i<30; i++)
{
WaitForSingleObject(allo,INFINITE);//等待tracker列印結束的訊號量
cout<<i<<endl;
fread(&op,sizeof(operation),1,file);
Sleep(op.time);//執行時間
GetSystemInfo(&info);
switch(op.protection)
{
case 0:
{
index=0;
temp=PAGE_READONLY;
break;
}
case 1:
temp=PAGE_READWRITE;
break;
case 2:
temp=PAGE_EXECUTE;
break;
case 3:
temp=PAGE_EXECUTE_READ;
break;
case 4:
temp=PAGE_EXECUTE_READWRITE;
break;
default:
temp=PAGE_READONLY;
}
switch(op.oper)
{
case 0:
{
cout<<"reserve now"<<endl;
traceArray[index].start=VirtualAlloc(NULL,op.block *info.dwPageSize,MEM_RESERVE,PAGE_NOACCESS);
traceArray[index++].size=op.block *info.dwPageSize;
cout<<"strating address:"<<traceArray[index-1].start<<'\t'<<"size:"<<traceArray[index-1].size<<endl;
break;
}
case 1:
{
cout<<"commit now"<<endl;
traceArray[index].start=VirtualAlloc(traceArray[index].start,traceArray[index].size,MEM_COMMIT,temp);
index++;
cout<<"strating address:"<<traceArray[index].start<<'\t'<<"size:"<<traceArray[index].size<<endl;
break;
}
case 2:
{
cout<<"lock now"<<endl;
cout<<"strating address:"<<traceArray[index].start<<'\t'<<"size:"<<traceArray[index].size<<endl;
if(!VirtualLock(traceArray[index].start,traceArray[index++].size))
cout<<GetLastError()<<endl;
break;
}
case 3:
{
cout<<"unlock now"<<endl;
cout<<"strating address:"<<traceArray[index].start<<'\t'<<"size:"<<traceArray[index].size<<endl;
if(!VirtualUnlock(traceArray[index].start,traceArray[index++].size))
cout<<GetLastError()<<endl;
break;
}
case 4:
{
cout<<"decommit now"<<endl;
cout<<"strating address:"<<traceArray[index].start<<'\t'<<"size:"<<traceArray[index].size<<endl;
if(!VirtualFree(traceArray[index].start,traceArray[index++].size,MEM_DECOMMIT))
cout<<GetLastError()<<endl;
break;
}
case 5:
{
cout<<"release now"<<endl;
cout<<"strating address:"<<traceArray[index].start<<'\t'<<"size:"<<traceArray[index].size<<endl;
if(!VirtualFree(traceArray[index++].start,0,MEM_RELEASE))
cout<<GetLastError()<<endl;
break;
}
default:
cout<<"error"<<endl;
}
ReleaseSemaphore(trac,1,NULL);
}
}
int main()
{
DWORD dwThread;
HANDLE handle[2];
handle[0]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)Tracker,NULL,0,&dwThread);
handle[1]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)Allocator,NULL,0,&dwThread);
allo=CreateSemaphore(NULL,0,1,"allo");
trac=CreateSemaphore(NULL,1,1,"trac");
WaitForMultipleObjects(2,handle,TRUE,INFINITE);
return 0;
}