频繁申请和回收内存,会导致在内存上产生大量的内存碎片,从而导致最终无法申请内存。DDK提供了Lookaside结构来解决这个问题。可以将Lookaside结构想象成一个内存容器。在初始的时候,它先向Windows申请了比较大的内存。以后每次申请内存的时候,不是直接向Windows申请内存,而是向Lookaside对象申请内存。
Lookaside一般会在以下情况下使用:
- 程序员每次申请固定大小的内存。
- 申请和回收的操作十分频繁。
初始化Lookaside:
1)VOID
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
);
(2)VOID
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 ", 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() "); }