Windows 内存管理


参考文献:

http://blog.csdn.net/wubin1124/article/details/3760242


工作集(内存): 可以这么理解, 此值就是该进程所占用的总物理内存. 但是这个值是由两部分组成, 即 '专用工作集' + '共享工作集'.

内存(专用工作集): 这对于一个进程是最重要的, 它代表了一个进程独占用了多少内存. 

内存(共享工作集): 这是该进程和别的进程共享的内存量. 通常, 这是加载一个 dll 所占用的内存. 

提交大小: 属于 Committed 那一类. 但是不一定在物理内存中, 有些可能位于交换文件中. 如果有一个程序, 原本占 500MB 内存, 但是绝大多数内存都不使用, 则可以通过 `EmptyWorkingSet` 向操作系统发送请求, 将此进程的不常用的内容从物理内存中换出到换页文件中保存, 如下图:





写在最后


0. 工作集, 即在物理内存中的数据的集合.

1. 工作集 = 专用 + 共享

2. 将所有的 "工作集" 相加后的值会大于任务管理器中内存占用的百分比, 因为百分比对共享内存进行排重了.

3. "提交大小" 和 "工作集" 是两个层面的概念, 大部分活跃进程的 "工作集" 会大于 "提交大小", 而大部分非活跃的进程 "工作集" 会小于 "提交大小", 但是两者没有绝对关系.

4. 虚拟内存: 就是换页文件.



分页文件:硬盘上一个或者多个隐藏文件pagefile.sysWindows用于存储未存入内存的部分程序和数据文件。页面文件和物理内存或随机存取内存(RAM)构成了虚拟内存。Windows会根据需要将数据从页面文件移至内存,或将数据从内存移至页面文件以便为新数据释放内存。也叫“交换文件”。


Windows使用工具集:

Sysinternals Suite

https://technet.microsoft.com/zh-cn/library/bb842062.aspx


分页和非分页内存
Windows规定有些虚拟内存页面是可以交换到磁盘的文件中的,这类内存被称为分页内存,而有些虚拟内存是不能被交换到磁盘的文件中,这些内存被称为非分页内存。当程序的中断请求在DISPATCH_LEVEL之上时,包括DISPATCH_LEVEL,程序只能使用非分页内存。

// WindbgCmdTest.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <iostream>
#include <Windows.h>
using namespace std;
#pragma comment(lib,"Psapi.lib")
#include <Psapi.h>

#define  MEM_M (1024*1024)
void OutputSystemMem(MEMORYSTATUS New, MEMORYSTATUS Old)
{
	//cout<<"减少物理内存="<<(New.dwAvailPhys-Old.dwAvailPhys)/MEM_M<<endl;
	//cout<<"减少可用页文件="<<(New.dwAvailPageFile-Old.dwAvailPageFile)/MEM_M<<endl;
	//cout<<"减少可用进程空间="<<(New.dwAvailVirtual-Old.dwAvailVirtual)/MEM_M<<endl;
}


static PROCESS_MEMORY_COUNTERS stLastMem;


void OutputProcessMem()
{
	PROCESS_MEMORY_COUNTERS pro;
	HANDLE handle = GetCurrentProcess();
	GetProcessMemoryInfo(handle, &pro, sizeof(pro));
	cout<<"缺页中断次数	"<<"new("<<pro.PageFaultCount/MEM_M<<") "<<"old("<<stLastMem.PageFaultCount/MEM_M<<")"<<endl;
	cout<<"使用内存高峰	"<<"new("<<pro.PeakWorkingSetSize/MEM_M<<") "<<"old("<<stLastMem.PeakWorkingSetSize/MEM_M<<")"<<endl;
	cout<<"当前使用的内存	"<<"new("<<pro.WorkingSetSize/MEM_M<<") "<<"old("<<stLastMem.WorkingSetSize/MEM_M<<")"<<endl;
	cout<<"使用页面缓存池高峰	"<<"new("<<pro.QuotaPeakPagedPoolUsage/MEM_M<<") "<<"old("<<stLastMem.QuotaPeakPagedPoolUsage/MEM_M<<")"<<endl;
	cout<<"使用页面缓存池	"<<"new("<<pro.QuotaPagedPoolUsage/MEM_M<<") "<<"old("<<stLastMem.QuotaPagedPoolUsage/MEM_M<<")"<<endl;
	cout<<"使用非分页缓存池高峰	"<<"new("<<pro.QuotaPeakNonPagedPoolUsage/MEM_M<<") "<<"old("<<stLastMem.QuotaPeakNonPagedPoolUsage/MEM_M<<")"<<endl;
	cout<<"使用非分页缓存池	"<<"new("<<pro.QuotaNonPagedPoolUsage/MEM_M<<") "<<"old("<<stLastMem.QuotaNonPagedPoolUsage/MEM_M<<")"<<endl;
	cout<<"使用分页文件(提交的内存文件大小)	"<<"new("<<pro.PagefileUsage/MEM_M<<") "<<"old("<<stLastMem.PagefileUsage/MEM_M<<")"<<endl;
	cout<<"使用分页文件高峰	"<<"new("<<pro.PeakPagefileUsage/MEM_M<<") "<<"old("<<stLastMem.PeakPagefileUsage/MEM_M<<")"<<endl;
	cout<<endl;
	memcpy(&stLastMem,&pro,sizeof(pro));
}
#define  VIRTUAL_ALLOC_TEST_SIZE 10*MEM_M
int _tmain(int argc, _TCHAR* argv[])
{
	memset(&stLastMem,0,sizeof(stLastMem));
	OutputProcessMem();

	MEMORYSTATUS memStatusVirtual;
	GlobalMemoryStatus(&memStatusVirtual);

	LPVOID pV=VirtualAlloc(NULL,VIRTUAL_ALLOC_TEST_SIZE,MEM_RESERVE|MEM_TOP_DOWN,PAGE_READWRITE);
	if(pV==NULL)
	{
		cout<<"没有那么多虚拟空间!"<<endl;
	}
	MEMORYSTATUS memStatusVirtual1;
	GlobalMemoryStatus(&memStatusVirtual1);
	cout<<"VirtualAlloc(NULL,1000*1024*1024,MEM_RESERVE|MEM_TOP_DOWN,PAGE_READWRITE);"<<endl;
	OutputSystemMem(memStatusVirtual1,memStatusVirtual);
	OutputProcessMem();


	cout<<"\n";
	pV=VirtualAlloc(pV,VIRTUAL_ALLOC_TEST_SIZE,MEM_COMMIT,PAGE_READWRITE);
	if (pV == NULL)
	{
		DWORD eLastError = GetLastError();
		cout <<"eLastError: %d" << eLastError;
	}
	MEMORYSTATUS memStatusVirtual2;
	GlobalMemoryStatus(&memStatusVirtual2);
	cout<<"VirtualAlloc(pV,10*1024*1024,MEM_COMMIT|MEM_RESERVE,PAGE_READWRITE);"<<endl;
	OutputSystemMem(memStatusVirtual2,memStatusVirtual1);
	OutputProcessMem();


	char * pC = (char *)pV;
	cout<<"\n";
	cout<<"pC[VIRTUAL_ALLOC_TEST_SIZE-1] = 0;;"<<endl;
	pC[VIRTUAL_ALLOC_TEST_SIZE-1] = 0;
	OutputProcessMem();


	cout<<"\n";
	char * p = new char[10*MEM_M];
	MEMORYSTATUS memStatusVirtual8;
	GlobalMemoryStatus(&memStatusVirtual8);
	cout<<"char * p = new char[10*MEM_M];"<<endl;
	OutputSystemMem(memStatusVirtual8,memStatusVirtual2);

	OutputProcessMem();


	cout<<"\n";
	VirtualFree(pV,VIRTUAL_ALLOC_TEST_SIZE,MEM_DECOMMIT);
	MEMORYSTATUS memStatusVirtual3;
	GlobalMemoryStatus(&memStatusVirtual3);
	cout<<"	VirtualFree(pV,10*1024*1024,MEM_DECOMMIT);"<<endl;
	OutputSystemMem(memStatusVirtual3,memStatusVirtual2);
	OutputProcessMem();

	cout<<"\n";
	VirtualFree(pV,VIRTUAL_ALLOC_TEST_SIZE,MEM_RELEASE);
	MEMORYSTATUS memStatusVirtual4;
	GlobalMemoryStatus(&memStatusVirtual4);
	cout<<"VirtualFree(pV,10*1024*1024,MEM_RELEASE);"<<endl;
	OutputSystemMem(memStatusVirtual4,memStatusVirtual3);
	OutputProcessMem();

	cout<<"\n";
	VirtualUnlock(pV,VIRTUAL_ALLOC_TEST_SIZE);
	MEMORYSTATUS memStatusVirtual5;
	GlobalMemoryStatus(&memStatusVirtual5);
	cout<<"VirtualUnlock(pV,10*1024*1024);"<<endl;
	OutputSystemMem(memStatusVirtual5,memStatusVirtual4);
	OutputProcessMem();


	cout<<"delete[] p;"<<endl;
	delete[] p;
	OutputProcessMem();

	getchar();
	return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值