在频繁的申请和释放内存中,在内存中会产生所谓的“空洞”,其实是Windows内存管理的不智能所造成的。
在《Windows驱动程序开发详解》第五章第三节中说到:在内存中先后申请三块内存,最开始可用的内存是连续的。当某个时刻内存块2被回收,如果系统想分配一块略大于原先内存块2的内存,这时原先的内存2就不能被申请成功。因此,频繁地申请、回收内存会导致在内存上产生大量的内存“空洞。”
对于这段话,可以理解为当在一段连续的内存中回收了中间的一个内存块时,Windows并不能立即(系统在空闲时会整理)对这种内存碎片进行整理,如果频繁进行这样的操作,那内存碎片就会越多,道理跟磁盘碎片相同。
而Lookaside对象是一个智能内存管理器,可以即时的对这样的内存“空洞”或是内存碎片进行整理,以达到节省内存的作用。
一、初始化Lookaside对象
ExInitalizeNPagedLookasideList 对非分页内存Lookaside对象初始化
ExInitalizePagedLookasideList 对分布内存Lookaside对象初始化
二、申请内存
ExAllocateFromNPagedLookasideList 申请非分页内存
ExAllocateFromPagedLookasideList 申请分页内存
三、回收内存
ExFreeToNPagedLookasideList 回收非分页内存
ExFreeToPagedLookasideList 回收分布内存
四、删除Lookaside对象
ExDeleteNPagedLookasideList
ExDeletePagedLookasideList
五、示例代码
VOID LookasideTest()
{
//初始化Lookaside对象
PAGED_LOOKASIDE_LIST pageList;
ExInitializePagedLookasideList( &pageList, NULL, NULL, 0, sizeof( MYDATASTRUCT ), '1234', 0 );
#define ARRAY_NUMBER 50
PMYDATASTRUCT MyObjectArray[ARRAY_NUMBER];
for ( int i = 0; i < ARRAY_NUMBER; i++ )
{
MyObjectArray[i] = ( PMYDATASTRUCT ) ExAllocateFromPagedLookasideList( &pageList );
KdPrint( ( "申请内存:%d", i ) );
}
//模拟频繁回收内存
for ( int i = 0; i < ARRAY_NUMBER; i++ )
{
ExFreeToPagedLookasideList( &pageList, MyObjectArray[i] );
MyObjectArray[i] = NULL;
KdPrint( ( "释放内存:%d", i ) );
}
//删除Lookaside对象
ExDeletePagedLookasideList( &pageList );
}