Windows内存管理(2)--Lookaside结构 和 运行时函数

1. Lookaside结构

频繁的申请和回收内存,会导致在内存上产生大量的内存“空洞”,从而导致最终无法申请内存。DDK为程序员提供了Lookaside结构来解决这个问题。

我们可以将Lookaside对象看成是一个内存容器。在初始化的时候,它先向Windows申请了一块比较大的内存。以后程序员每次申请内存的时候,不是直接向Windows申请内存,而是想Lookaside对象申请内存。Looaside会智能的避免产生内存“空洞”。如果Lookaside对象内部内存不够用时,它会向操作系统申请更多的内存。

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

1. 程序员每次申请固定大小的内存。

2. 申请和回收的操作十分频繁。

要使用Looaside对象,首先要初始化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
);

初始化玩Lookaside对象后,可以进行申请内存的操作了:

1)PVOID
ExAllocateFromNPagedLookasideList(
IN PNPAGED_LOOKASIDE_LIST
Lookaside
);

2)PVOID
ExAllocateFromPagedLookasideList(
IN PPAGED_LOOKASIDE_LIST
Lookaside
);

Lookaside对象回收内存:

1)VOID
ExFreeToNPagedLookasideList(
IN PNPAGED_LOOKASIDE_LIST
Lookaside,
IN PVOID
Entry
);

2)VOID
ExFreeToPagedLookasideList(
IN PPAGED_LOOKASIDE_LIST
Lookaside,
IN PVOID
Entry
);

在使用完Lookaside对象后,要删除Lookaside对象:

1)VOID
ExDeleteNPagedLookasideList(
IN PNPAGED_LOOKASIDE_LIST
Lookaside
);

(2) VOID
ExDeletePagedLookasideList(
IN PPAGED_LOOKASIDE_LIST
Lookaside
);

测试代码:

#pragma INITCODE VOID LookasideTets() { KdPrint(("进入LookasideTest函数!\n")); PAGED_LOOKASIDE_LIST Lookaside; ExInitializePagedLookasideList(&Lookaside, NULL, NULL, 0, sizeof(MYDATASTRUCT), 'abcd', 0); PMYDATASTRUCT pMyData[50]; for (int i=0; i<50; i++) { pMyData[i] = (PMYDATASTRUCT)ExAllocateFromPagedLookasideList(&Lookaside); if ((i+1)%10 == 0) { KdPrint(("申请了 %d 个数据了!\n", ++i)); } } for (int i=0; i<50; i++) { ExFreeToPagedLookasideList(&Lookaside, pMyData[i]); pMyData[i] = NULL; if ((i+1)%10 == 0) { KdPrint(("释放了 %d 个数据的内存了!\n", ++i)); } } ExDeletePagedLookasideList(&Lookaside); }


2.运行时函数

(1)内存间复制(非重叠)

VOID
RtlCopyMemory(
IN VOID UNALIGNED *
Destination,
IN CONST VOID UNALIGNED *
Source,
IN SIZE_T
Length
);

(2)内存间复制(可重叠)

VOID
RtlMoveMemory(
IN VOID UNALIGNED
*Destination,
IN CONST VOID UNALIGNED *
Source,
IN SIZE_T
Length
);

3)填充内存

VOID
RtlFillMemory(
IN VOID UNALIGNED
*Destination,
IN SIZE_T
Length,
IN UCHAR
Fill
);

VOID
RtlZeroMemory(
IN VOID UNALIGNED
*Destination,
IN SIZE_T
Length
);

4)内存比较

SIZE_T
RtlCompareMemory(
IN CONST VOID
*Source1,
IN CONST VOID
*Source2,
IN SIZE_T
Length
);

ULONG
RtlEqualMemory(
CONST VOID *
Source1,
CONST VOID *
Source2,
SIZE_T
Length
);

#define BUFFER_SIZE 1024 #pragma INITCODE VOID RtlTest() { KdPrint(("进入RtlTest函数!\n")); PUCHAR pBuffer1 = (PUCHAR)ExAllocatePool(PagedPool, BUFFER_SIZE); RtlZeroMemory(pBuffer1, BUFFER_SIZE); PUCHAR pBuffer2 = (PUCHAR)ExAllocatePool(PagedPool, BUFFER_SIZE); RtlFillMemory(pBuffer2, BUFFER_SIZE, 0xAA); RtlCopyMemory(pBuffer1, pBuffer2, BUFFER_SIZE); if (RtlEqualMemory(pBuffer1, pBuffer2, BUFFER_SIZE)) { KdPrint(("两块内存块数据一样!\n")); for(int i=0; i<BUFFER_SIZE; i++) { KdPrint(("%02X", pBuffer1[i])); } } else { KdPrint(("两块内存块数据不一样!\n")); } KdPrint(("离开RtlTest函数!\n")); }


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值