内存管理:堆方式

内存管理方式--堆

每个进程都会提供一个默认的堆,可以让程序人员自己进行操纵,这样给予了程序开发人员很大的自由度,除了进程默认的堆(由进程自己创建和自己销毁),我们还可以自己在进程空间自己创建堆和释放堆,并在堆中申请空间和释放空间。


需要我们自己创建堆的理由:

1. 如果多个线程对堆进行访问,那么在为线程分配空间时,很明显的,我们需要对其进行互斥,而保证访问的安全性,但是有个办法是,我们可以每个线程拥有自己的堆,那么就无需担心因为互斥而带来的效能影响。

2. 对程序的保护,比如说堆中有一个链表和一颗二叉树,两者在堆中是混合的,如果因为链表操作的失误而覆盖了二叉树的数据,那么在进行二叉树的访问是有可能导致错误,我们还会以为是二叉树的问题!(这个我在程序中吃过亏,由于其他地方的原因覆盖了我的数据,让我在一个没有错误的代码花费了大量的时间)。

3. 提高内存的使用效率, 如果有很多大小不一致的数据结构放置于同一个堆中,那么某些结构空间的释放,并不能得到其他结构的利用,因为空间大小不够,就是内存碎片,如果我们把内存大小一致的数据结构放置于同一个堆中,那么内存的使用效率高多了!

4. 提高内存的访问效率,如果我们把需要同时访问的对象放在同一个堆中,而不是很分散的情况下,很多对象放置同一个页面或者相邻的页面,这样在遍历的时候如果内存页面不在时,将页面置换后可以访问到大量需要同时访问的数据,如果数据比较分散,访问了一个数据之后,查找下一个数据,发现不在内存中,还需要页面置换载入内存,频繁的这样,效率肯定比较低,因为IO是很影响效率的。

 

相关接口:

1. 获取进程的默认堆
HANDLE GetProcessHeap();

2. 堆的创建
HANDLE HeapCreate(DWORD fdwOptions, SIZE_T dwInitialSize, SIZE_T dwMaximumSize);
fdwOptions:堆的操作选项
dwInitialSize:给堆分配的初始大小
dwMaximumSize:堆能够增长到最大大小

3.从堆中分配空间
PVOID HeapAlloc(HANDLE hHeap, DWORD fdwFlags, SIZE_T dwBytes);

4. 释放空间
BOOL HeapFree(HANDLE hHeap, DWORD fdwFlags, PVOID pvMem);

5. 堆的销毁
BOOL HeapDestory(HANDLE hHeap);

简单示例:

这个例子来自于WINDOWS核心编程
这个例子的主要思想就是,我们可以把同一个类型的对象,都放入到同一个堆当中,避免和其他不同类型的对象放在
一起,导致的相关内存碎片问题。

class CTestClass
{
    public:
	static HANDLE hHeap;
	static int    nAllocNum;

    public: 
	int m_nAge;
	char m_strName[20];

	void* operator new(size_t size);
	void  operator delete(void* p);
};

HANDLE CTestClass::hHeap = NULL;
int    CTestClass::nAllocNum = 0;

void* CTestClass::operator new(size_t size)
{
	if (hHeap == NULL)
    	     hHeap  = HeapCreate(HEAP_ZERO_MEMORY | HEAP_GENERATE_EXCEPTIONS,0, 0);
            
        void* p = HeapAlloc(hHeap, HEAP_ZERO_MEMORY, size);
	
	if (p)
	    nAllocNum++;

	return p;
};

void CTestClass::operator delete(void* p)
{
	if (hHeap)
	{
		if (nAllocNum == 0)
		{
			HeapDestroy(hHeap);
			return;
		}

		HeapFree(hHeap, 0, p);
		nAllocNum--;
	}
}


int _tmain(int argc, _TCHAR* argv[])
{
	//申请空间
	CTestClass* pTest =(CTestClass*) (new CTestClass());
	
	//模拟下构造函数
	((CTestClass*)pTest)->m_nAge = 10;
	char content[] =  "Hello, Word";
	memcpy(((CTestClass*)pTest)->m_strName, content, 11);
	cout<<"Name:"<<pTest->m_strName<<endl;
	cout<<"Age:	"<<pTest->m_nAge<<endl;

	//释放空间
	delete pTest;
	getchar();
	return 0;
}

参考:WINDOWS核心编程第五版

转载于:https://my.oschina.net/myspaceNUAA/blog/68188

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值