您的位置:首页 > 其它

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

2014-02-28 10:23 120 查看
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)VOID

ExFreeToNPagedLookasideList(

IN PNPAGED_LOOKASIDE_LIST
Lookaside,

IN PVOID
Entry

)

(2)VOID

ExFreeToPagedLookasideList(

IN PPAGED_LOOKASIDE_LIST
Lookaside,

IN PVOID
Entry

);

测试代码:

#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

);

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"));
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: