Lookaside

时间:2023-03-09 13:10:53
Lookaside

  频繁申请和回收内存,会导致在内存上产生大量的内存碎片,从而导致最终无法申请内存。DDK提供了Lookaside结构来解决这个问题。可以将Lookaside结构想象成一个内存容器。在初始的时候,它先向Windows申请了比较大的内存。以后每次申请内存的时候,不是直接向Windows申请内存,而是向Lookaside对象申请内存。

  

  Lookaside一般会在以下情况下使用:

  1. 程序员每次申请固定大小的内存。
  2. 申请和回收的操作十分频繁。

  初始化Lookaside:

  1VOID 
    ExInitializeNPagedLookasideList(
      IN PNPAGED_LOOKASIDE_LIST  Lookaside,
      IN PALLOCATE_FUNCTION  Allocate  OPTIONAL,
      IN PFREE_FUNCTION  Free  OPTIONAL,
      IN ULONG  Flags,
      IN SIZE_T  Size,
      IN ULONG  Tag,
      IN USHORT  Depth
      );

  (2VOID 
    ExInitializePagedLookasideList(
      IN PPAGED_LOOKASIDE_LIST  Lookaside,
      IN PALLOCATE_FUNCTION  Allocate  OPTIONAL,
      IN PFREE_FUNCTION  Free  OPTIONAL,
      IN ULONG  Flags,
      IN SIZE_T  Size,
      IN ULONG  Tag,
      IN USHORT  Depth
      );

  申请内存:

  ExInitializeNPagedLookasideList()

  ExInitializePagedLookasideList()

  回收内存:

  ExFreeToNPagedLookasideList()

  ExFreeToPagedLookasideList()

  删除Lookaside对象:

  ExDeleteNPagedLookasideList()

  ExDeletePagedLookasideList()

//bp Lookaside!DriverEntry

NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegisterPath)
{
NTSTATUS Status = STATUS_SUCCESS;
PDEVICE_OBJECT DeviceObject = NULL;
DriverObject->DriverUnload = DriverUnload;
SeLookaside();
return Status;
}
VOID SeLookaside()
{
//初始化Lookaside对象
int i = 0;
PAGED_LOOKASIDE_LIST PagedLookasideList;
ExInitializePagedLookasideList(&PagedLookasideList, NULL, NULL, 0, sizeof(ITEM), '8888', 0); #define ARRAY_NUMBER 50
PITEM Item[ARRAY_NUMBER];
//模拟频繁申请内存
for (i = 0; i < ARRAY_NUMBER; i++)
{
Item[i] = (PITEM)ExAllocateFromPagedLookasideList(&PagedLookasideList);
} for (i = 0;i<ARRAY_NUMBER;i++)
{
Item[i]->ItemData = i;
} for (i = 0; i < ARRAY_NUMBER; i++)
{
DbgPrint("%d\r\n", Item[i]->ItemData);
}
//模拟频繁回收内存
for (i = 0; i < ARRAY_NUMBER; i++)
{
ExFreeToPagedLookasideList(&PagedLookasideList, Item[i]);
Item[i] = NULL;
} ExDeletePagedLookasideList(&PagedLookasideList);
//删除LookasidePagedLookasideList
} VOID DriverUnload(PDRIVER_OBJECT DriverObject)
{
DbgPrint("DriverUnload()\r\n");
}