工作集管理器是被平衡集管理器所调用,通过设置信号的方式来驱动整个内存管理策略,例如工作集修剪等。各个管理器具体负责的职责,上面已经列明,比较好理解,但是它们彼此之间的关系,特别是工作集管理器是如何被系统所驱动的?所以为了更好理解,接下来从内存管理的初始化开始分析:
内存管理的初始化例程是MmInitSystem,在 ntoskrnl的初始化工作的phase 0 和 phase 1被调用,它在WRK中是被遮掩描述的: This function is called during Phase 0, phase 1 and at the end of phase 1 ("phase 2") initialization.
Phase 0 initializes the memory management paging functions,
nonpaged and paged pool, the PFN database, etc.
Phase 1 initializes the section objects, the physical memory
object, and starts the memory management system threads.
Phase 2 frees memory used by the OsLoader.
其中在phase 1的 时候创建启动了两个线程: KeBalanceSetManager(平衡集管理器)和 KeSwapProcessOrStack(交换管理器)代码如下
//
// Start the balance set manager.
//
// The balance set manager performs stack swapping and working
// set management and requires two threads.
//
InitializeObjectAttributes (&ObjectAttributes, NULL, 0, NULL, NULL);
if (!NT_SUCCESS(PsCreateSystemThread (&ThreadHandle,
THREAD_ALL_ACCESS,
&ObjectAttributes,
0L,
NULL,
KeBalanceSetManager,
NULL))) {
return FALSE;
}
ZwClose (ThreadHandle);
if (!NT_SUCCESS(PsCreateSystemThread (&ThreadHandle,
THREAD_ALL_ACCESS,
&ObjectAttributes,
0L,
NULL,
KeSwapProcessOrStack,
NULL))) {
return FALSE;
}
ZwClose (ThreadHandle);
KeBalanceSetManager:等待两个事件对象(其中一个有信号即可): MmWorkingSetManagerEvent (a memory management memory low event, a swap event), PeriodTimer (the expiration of the period timeout rate that the balance set manager runs at.),然后调用MmWorkingSetManager完成 working set 的管理(分析、调整、修剪等)
VOID
KeBalanceSetManager (
IN PVOID Context
)
{
.........
do {
//等待事件信号
Status = KeWaitForMultipleObjects(MaximumObject,
&WaitObjects[0],
WaitAny,
Executive,
KernelMode,
FALSE,
NULL,
&WaitBlockArray[0]);
//
// Switch on the wait status.
//
switch (Status) {
//定时器唤醒
case TimerExpiration:
//
// Adjust I/O lookaside credits.
//
#if !defined(NT_UP)
KiAdjustIrpCredits();
#endif
//
// Adjust the depth of lookaside lists.
//
ExAdjustLookasideDepth();
//
// Execute the virtual memory working set manager.
//
[B]MmWorkingSetManager();//调用[/B]
//
// Attempt to initiate outswapping of kernel stacks.
//
// N.B. If outswapping is initiated, then the dispatcher
// lock is not released until the wait at the top
// of the loop is executed.
//
StackScanPeriod -= 1;//计数,
if (StackScanPeriod == 0) {
StackScanPeriod = StackScanTime;//一般是4(有一种情况是8),就是每第四次被1秒钟定时器唤醒时,才驱动交换管理器
if (InterlockedCompareExchange(&KiStackOutSwapRequest,
TRUE,
FALSE) == FALSE) {
KiLockDispatcherDatabase(&OldIrql);
KiSetInternalEvent(&KiSwapEvent, KiSwappingThread);
Thread = KeGetCurrentThread();
Thread->WaitNext = TRUE;
Thread->WaitIrql = OldIrql;
}
}
break;
//低内存事件
case WorkingSetManagerEvent:
//
// Call the working set manager to trim working sets.
//
[B]MmWorkingSetManager();//调用[/B]
break;
..........
}