欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Lookaside结构

程序员文章站 2024-01-23 16:14:52
...

在内核中,频繁的申请和释放内存。容易造成大量的内存碎片。
ddk提供了一种解决方式,使用Lookaside对象。该对象会一次性申请一个大的内存,以后每次需要内存的时候就到这个对象中去拿
Lookaside对象内部的内存不够用时,它会向操作系统申请更多的内存。当Lookaside对象
内部有大量的未使用的内存时,它会自动让Windows回收一部分内存。 总之,Lookaside
是一个自动的内存分配容器。通过对Lookaside对象申请内存,效率要高于直接向Windows
申请内存。Lookaside 一-般会在以下情况使用:
(1)程序员每次申请固定大小的内存。
(2)申请和回收的操作十分频繁。
如果程序员遇到上述两种情况,可以考虑使用Lookaside 对象。驱动程序中的运行效
率是程序员必须考虑的问题。如果驱动程序的运行效率低,会严重影响到操作系统的性能。
使用Lookaside对象,首先要初始化Lookaside对象,有以下两个函数可以使用:

非分页内存

void ExInitializeNPagedLookasideList(
  PNPAGED_LOOKASIDE_LIST Lookaside,
  PALLOCATE_FUNCTION     Allocate,
  PFREE_FUNCTION         Free,
  ULONG                  Flags,
  SIZE_T                 Size,
  ULONG                  Tag,
  USHORT                 Depth
);

分页内存

void ExInitializePagedLookasideList(
  PPAGED_LOOKASIDE_LIST Lookaside,
  PALLOCATE_FUNCTION    Allocate,
  PFREE_FUNCTION        Free,
  ULONG                 Flags,
  SIZE_T                Size,
  ULONG                 Tag,
  USHORT                Depth
);

初始化Lookaside结构后,就可以申请内存了。
同样也有两个申请内存的函数
非分页内存申请方式

PVOID ExAllocateFromNPagedLookasideList(
  PNPAGED_LOOKASIDE_LIST Lookaside
);

分页内存申请方式

PVOID ExAllocateFromPagedLookasideList(
  PPAGED_LOOKASIDE_LIST Lookaside
);


对Lookaside对象回收内存的操作(也就是ExAllocateFromNPagedLookasideList申请分配的非分页内存或者ExAllocateFromPagedLookasideList申请的分页内存),有以下两个函数:

void ExFreeToNPagedLookasideList(
  PNPAGED_LOOKASIDE_LIST Lookaside,
  PVOID                  Entry
);

void ExFreeToPagedLookasideList(
  PPAGED_LOOKASIDE_LIST Lookaside,
  PVOID                 Entry
);

删除Lookaside对象

void ExDeleteNPagedLookasideList(
  PNPAGED_LOOKASIDE_LIST Lookaside
);
void ExDeletePagedLookasideList(
  PPAGED_LOOKASIDE_LIST Lookaside
);

模拟多次内存申请和释放

#include<ntddk.h>

typedef struct _MYDATASTRUCT
{
	//下面是自定义的数据
	ULONG x;
	ULONG y;
	// List Entry需要作为MYDATASTRUCT结构体的一部分
	LIST_ENTRY ListEntry;


}MYDATASTRUCT, *PMYDATASTRUCT;

void DriverUnload(PDRIVER_OBJECT pDriverObject)
{
	DbgPrint("unload");
}
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pReg)
{
	PMYDATASTRUCT MyObjectArr[500];
	//申明一个PAGED_LOOKASIDE_LIST对象,用于接收初始化后的数据
	PAGED_LOOKASIDE_LIST pageList;
	
	//初始化PAGED_LOOKASIDE_LIST结构
	ExInitializePagedLookasideList(&pageList,0,0,0,sizeof(MYDATASTRUCT),'1234',0);
	
	for (ULONG i = 0; i < 500;i++)
	{
		//在已经分配好的Lookasdide对象中申请内存。
		MyObjectArr[i] = (PMYDATASTRUCT)ExAllocateFromPagedLookasideList(&pageList);
		
	}

	for (ULONG i = 0; i < 500; i++)
	{
		//释放申请的内存
		ExFreeToPagedLookasideList(&pageList, MyObjectArr[i]);
		MyObjectArr[i] = NULL;
		

	}
	//删除Lookasdide对象
	ExDeletePagedLookasideList(&pageList);
	pDriverObject->DriverUnload = DriverUnload;
	return STATUS_SUCCESS;
}