Windows運用AVL樹對進程地址空間的管理

32位Windows系統中,進程在用戶態可用的地址空間範圍是低2G(x64下是低8192G)。隨着進程不斷的申請和釋放內存,這個2G的地址空間,有的地址範圍是保留狀態(reserved),有的地址範圍是提交狀態(映射到了物理頁面,committed),有的地址範圍是空閒的。Windows採用平衡二叉樹把這些離散的地址範圍管理起來。

常見的平衡二叉樹有紅黑樹和AVL樹兩種,其中紅黑樹應用更廣,C#/Java/C++STL等若干數據結構內部都是用紅黑樹實現的,然而Windows這次選擇了AVL樹。根據 《數據結構與算法C語言描述》,AVL樹的最大高度是1.44 * log(N+2) - 1.328,紅黑樹的最大高度是2.00* log(N+1)。與紅黑樹相比,AVL樹的插入刪除操作更慢一些,但是查詢操作更快。想必對進程地址空間的查詢操作更頻繁一些,所以AVL得以入選。

AVL樹的節點結構是

typedef struct _MMADDRESS_NODE {
    ULONG_PTR StartingVpn;  // 起始虛擬地址
    ULONG_PTR EndingVpn;   // 終止虛擬地址
    struct _MMADDRESS_NODE *Parent;
    struct _MMADDRESS_NODE *LeftChild;
    struct _MMADDRESS_NODE *RightChild;
} MMADDRESS_NODE, *PMMADDRESS_NODE;

AVL樹的根節點保存在進程內核對象_EProcess中。_EProcess的結構沒有出現在文檔中,但是我們可以通過windbg獲取。在Windows 2003中,用windbg獲取如下輸出:

kd> dt _EProcess
nt!_EPROCESS
   +0x000 Pcb              : _KPROCESS
   +0x078 ProcessLock      : _EX_PUSH_LOCK
   +0x080 CreateTime       : _LARGE_INTEGER
   +0x088 ExitTime         : _LARGE_INTEGER
   ……
   +0x24c PriorityClass    : UChar
   +0x250 VadRoot          : _MM_AVL_TABLE
   +0x270 Cookie           : Uint4B

上圖中偏移量爲0x250處的VadRoot字段保存了AVL輸根節點所在的地址。因此,在驅動程序中,通過以下代碼可以獲取當前進程的AVL樹的根節點地址。


PMMADDRESS_NODE ZsaGetVmRoot(){
	char * pEProcess = (char*)PsGetCurrentProcess();
	char * avlRoot = pEProcess + 0x250;
	char * p_MM_AVL_TABLE = avlRoot;
	return (PMMADDRESS_NODE) p_MM_AVL_TABLE;
}

既然獲得了根地址,則可以對二叉樹進行遍歷,打印出整個數據結構。以下是某個測試進程在進行了1024*1024次new分配後,AVL樹的內容。可以看到,樹基本是平衡的。

 

 

0,0

├─────N

└─────280,2b3

            ├─────150,24f

            │          ├─────130,134

            │          │          ├─────20,20

            │          │          │          ├─────10,10

            │          │          │          └─────30,12f

            │          │          └─────140,140

            │          └─────260,275

            │                      ├─────250,25f

            │                      └─────N

            └─────10200,10372

                        ├─────400,502

                        │          ├─────310,315

                        │          │          ├─────2c0,300

                        │          │          └─────370,37f

                        │          │                      ├─────320,360

                        │          │                      └─────380,382

                        │          └─────c10,140f

                        │                      ├─────610,80f

                        │                      │          ├─────510,60f

                        │                      │          └─────810,c0f

                        │                      └─────2410,440f

                        │                                  ├─────1410,240f

                        │                                  └─────4410,840f

                        └─────7c930,7c9ff

                                   ├─────10540,1853f

                                   │          ├─────10480,10536

                                   │          └─────7c800,7c92a

                                   │                      ├─────18540,2853f

                                   │                      └─────N

                                   └─────7ffdd,7ffdd

                                               ├─────7ffa0,7ffd2

                                               │          ├─────7f6f0,7f7ef

                                               │          └─────N

                                                └─────7ffde,7ffde
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章