首先分配一个块内存, 然后让系统自己进行管理
针对这块内存判断其属性是分页的,还是非分页的。分别调用不同的函数, 来初始化这块 内存,来构造一个Lookaside表。
分页的使用ExInitializePagedLookasideList函数
非分页的使用 ExInitializeNonpagedLookasideList函数
ExInitializepagedLookasideList的函数定义
VOID
ExInitializePagedLookasideList(
IN PPAGED_LOOKASIDE_LIST Lookaside, <----- 先分配的一块内存(分页的)
IN PALLOCATE_FUNCTION Allocate OPTIONAL, <----- 可选, 一般不用
IN PFREE_FUNCTION Free OPTIONAL, <----- 可选, 一般不用
IN ULONG Flags, // 0, -- Reserved
IN SIZE_T Size, // 将要让Lookaside管理的结构的大小, KmdKit中的例子使用的My_Structure的结构.
IN ULONG Tag, // 启个名称来标示
IN USHORT Depth // 0 , -- Reserved
);
要使用这个Lookaside管理下的内存时, 调用ExAllocateFromPagedLookasideList
将上面的Lookaside的参数放入即可.
返回的指针就是上面设置好大小的一块内存区域.
KMDKIT中的示例, 通过InsertHeadList将这块内存插入到一个双向列表中.
InsertHeadList arg1 ------- HeadList
arg2 ------- My_Structure 的 ENTRY_LIST 字段
用RemoveHeadList来删除.
ExFreeToPagedLookasideList后面跟两个参数.
一个是 Lookaside
第二是 所要释放的块, 和分配时保持一致, 分配时是该块的首地址, 所以...
以下摘自 KmdKit 的教程
后备列表是一组事先分配的相同尺寸的内存块。这些块有些在使用,有些没被使用。
当有内存分配请求的时候,系统会遍历这个列表寻找最近的未分配的块。
如果未分配的块找到了,分配请求就很快被满足了。
否则系统必须从分页或不分页内存池去分配。根据列表中分配行为发生的频率,
系统会自动调整未分配块的数量来满足分配请求,分配的频率越高,
会有越多的块被存储在后备列表中。后备列表如果总是不被使用,
也会自动减少空间大小。
PS: 使用Lookaside链表的优点就是可以比较快的从已分配的内存中得到满足.
并且不用考虑内存扩大的影响, 并且要求内存分配速度太高.
如果内存分配速度太高,那么跟内存池分配方式比,就没有性能的优势了.
不过这是一个在内核态才有的东东, 可惜呀.