JIURL play Win2k articles LookasideList of memory: JIURL Home: http://jiurl.yeah.net Date: 2003-7-30
Introduction to the system's pile of systems The stack of systems is a systematic data dynamic application and place. Win2k called the system pile of pool. Depending on whether you can be replaced out of physical memory, divided into PagedPool and NonPagedPool. There are many structures in Lookasidelist Windows 2000, which require dynamic applications. That is, the application is applied in the system's pool. Applying and releaseing memory in pool is relatively slow, because the application is required to find a suitable size of idle blocks in pool, and consider the inclusion of idle blocks, etc. when it is released. There are many fixed-size structures in the system require dynamic allocation. In order to improve efficiency, the system uses lookasidelist. There are many Lookasidelist in Windows 2000. Some kind of Lookasidelist application is fixed. Lookasidelist applies for memory from Paged Pool or Nonpaged Pool. For block released on lookasidelist, it is not directly released into pool, and it is possible to put on lookasidelist, so if there is another application, you don't have to find the right size idle block in Pool, but can directly Take away it. That is, it is still an application, it is still going to POOL to apply for a certain size memory. But when it is released, it is very likely that it does not release back to the pile, but is reserved by LOOKASIDELIST, it is used for re-application. Later, we will find that the number of LOOKASIDELIST in the system is a lot. If the application is not released, it is not to take a lot of memory whitening, which may lead to someone's new application for less than memory? Don't worry, every lookasidelist is only a few of the few pieces. If it exceeds it, it will be released back to Pool. The system also checks. Windows 2000 puts a lot of lookasidelist chains on two chains. According to the LOOKASIDELIST, it applies for memory from the Paged Pool or from the NonPaged Pool. The LOOKASIDELIST chain applied for memory from the Paged Pool on PagedLookasidelist. The LOOKASIDELIST chain applied for memory from the nonpaged pool in NPagedLookasidelist. There are two kindlist (NPAGED_LOOKASIDE_LIST and PAGED_LOOKASIDE_LIST) and its related structures. They can also be defined by KD.
typedef struct _NPAGED_LOOKASIDE_LIST {GENERAL_LOOKASIDE L; KSPIN_LOCK Lock;} NPAGED_LOOKASIDE_LIST, * PNPAGED_LOOKASIDE_LIST; typedef struct _PAGED_LOOKASIDE_LIST {GENERAL_LOOKASIDE L; FAST_MUTEX Lock;} PAGED_LOOKASIDE_LIST, * PPAGED_LOOKASIDE_LIST;! kd> strct GENERAL_LOOKASIDE strct GENERAL_LOOKASIDEstruct _GENERAL_LOOKASIDE (sizeof = 72) 00 union _SLIST_HEADER! ListHead 00 uint64 Alignment 00 struct _SINGLE_LIST_ENTRY Next 00 struct _SINGLE_LIST_ENTRY * Next 04 uint16 Depth 06 uint16 Sequence 08 uint16 Depth 0a uint16 MaximumDepth 0c uint32 TotalAllocates 10 uint32 AllocateMisses 10 uint32 AllocateHits 14 uint32 TotalFrees 18 UINT32 FreeMisses 18 uint32 freehits 1C INT32 TYPE / / shows that NPAGED or PAGED. NPAGED is indicated 0. To 1 indicate the paged. 20 UINT32 TAG / / 4 bytes, usually in 4 letters as markers. For example, ObpCreateInfolookasiDelist uses "OBCI". 24 uint32 size // This size of the Lookasidelist. 28 function * Allocate // application functions are usually provided ExAllocatePoolWithTag 2c function * Free // release function, is generally put ExFreePool 30 struct _LIST_ENTRY ListEntry 30 struct _LIST_ENTRY * Flink 34 struct _LIST_ENTRY * Blink // here the same type (NPAGED or PAGED) LOOKASIDELIST chain together.
38 uint32 LastTotalAllocates 3c uint32 LastAllocateMisses 3c uint32 LastAllocateHits 40 uint32 Future [2] typedef struct _SINGLE_LIST_ENTRY {struct _SINGLE_LIST_ENTRY * Next;} SINGLE_LIST_ENTRY, * PSINGLE_LIST_ENTRY; kd Here we use these two lists are traversed to traverse PagedLookasideListkd> ExPagedLookasideListHead?? ExPagedLookasideListHeadEvaluate expression: -2142817432 = 80473368 // global variable ExPagedLookasideListHead kd> strct LIST_ENTRY ExPagedLookasideListHead strct LIST_ENTRY ExPagedLookasideListHeadstruct _LIST_ENTRY (sizeof = 8) 0 struct _LIST_ENTRY * Flink = 8046A9D0 4 struct _LIST_ENTRY * Blink = the 810EAF38 // PagedLookasideList chain!! ! LIST_ENTRY ListEntry PAGED_LOOKASIDE_LIST structure strct PAGED_LOOKASIDE_LISTstruct _PAGED_LOOKASIDE_LIST (sizeof = 104) ... 30 struct _LIST_ENTRY ListEntry ... kd> 8046A9D0-30 8046A9D0-30Evaluate expression:?? -2142852704 = 8046a9a0 // verify kd> lookaside! 8046A9A0! LOOKASIDE 8046A9A0LOOKASIDE "@ 8046a9a0" tunl "type = 0001 PagedPoolCurrent Depth = 1 max depth = 4Size = 136 max alloc = 544allocatem isses = 293 FreeMisses = 283TotalAllocates = 478 TotalFrees = 469Hit Rate = 38% Hit Rate = 39% kd>! strct PAGED_LOOKASIDE_LIST 8046a9a0! strct PAGED_LOOKASIDE_LIST 8046a9a0struct _PAGED_LOOKASIDE_LIST (sizeof = 104) 00 struct _GENERAL_LOOKASIDE L 00 union _SLIST_HEADER ListHead 00 uint64 Alignment = 01730001e35116c8 00 struct _SINGLE_LIST_ENTRY Next 00 struct _SINGLE_LIST_ENTRY * Next = E35116C8 04 uint16 Depth = 0001 06 uint16 Sequence = 0173 08 uint16 Depth = 0004 0a uint16 MaximumDepth = 0100 0c uint32 TotalAllocates = 000001de
10 uint32 AllocateMisses = 00000125 10 uint32 AllocateHits = 00000125 14 uint32 TotalFrees = 000001d5 18 uint32 FreeMisses = 0000011b 18 uint32 FreeHits = 0000011b 1c int32 Type = 00000001 // 1 = PagedPool 20 uint32 Tag = 4c6e7554 24 uint32 Size = 00000088 // 0x88 = 136 28 function * Allocate = 80466C80 2c function * Free = 80467297 30 struct _LIST_ENTRY ListEntry 30 struct _LIST_ENTRY * Flink = 804734B0 34 struct _LIST_ENTRY * Blink = 80473368 38 uint32 LastTotalAllocates = 000001dd 3c uint32 LastAllocateMisses = 00000125 3c uint32 LastAllocateHits = 00000125 40 uint32 Future [2] = 00000000 00000000 .... .... 48 struct _FAST_MUTEX Lock 48 int32 Count = 00000001 4c struct _KTHREAD * Owner = 00000000 50 uint32 Contention = 00000000 54 struct _KEVENT Event 54 struct _DISPATCHER_HEADER Header 54 byte Type = 01. 55 byte Absolute = 00. 56 byte Size = 04. 57 byte Inserted = 00. 58 int32 SignalState = 00000000 5c struct _LIST_ENTRY WAITLISTHEAD 5C STRUCT _LIST_ENTRY * FLINK = 8046A9FC // 60 Struct _ LIST_ENTRY * Blink = 8046A9FC 64 uint32 OldIrql = 00000000 kd> dd ExPagedLookasideListHead l 2dd ExPagedLookasideListHead l 280473368 8046a9d0 810eaf38 // remember that we are starting from ExPagedLookasideListHead 80473368, 80473368 // when we see again, says the chain has a cycle.
kd> dd $ pl 2dd $ pl 28046a9d0 804734b0 80473368kd> 804734b0 80473730 8046a9d0kd> 80473730 804802f0 804734b0kd> 804802f0 80480a90 80473730kd> 80480a90 fcccd4b0 804802f0kd> fcccd4b0 fcccd590 80480a90kd> fcccd590 810eba38 fcccd4b0kd> 810eba38 810eb918 fcccd590kd> 810eb918 810eb898 810eba38kd> 810eb898 810eb818 810eb918kd> 810eb818 810eb798 810eb898kd> 810eb798 810eb718 810eb818kd> 810eb718 810eb698 810eb798kd> 810eb698 810ea038 810eb718kd> 810ea038 810eafb8 810eb698kd> 810eafb8 810eaf38 810ea038kd> 810eaf38 80473368 810eafb8kd> 80473368 8046a9d0 810eaf38 // we saw 80,473,368, represents the chain has a cycle traverse NPagedLookasideList kd>? ExNPagedLookasideListHead? ExNPagedLookasideListHeadEvaluate expression: -2142817416 = 80473378kd> strct LIST_ENTRY ExNPagedLookasideListHead strct LIST_ENTRY ExNPagedLookasideListHeadstruct _LIST_ENTRY (sizeof = 8) 0 struct _LIST_ENTRY * Flink = 8047F8D0 4 struct _LIST_ENTRY * Blink = EEFFEC90kd> strct NPAGED_LOOKASIDE_LIST strct NPAGED_LOOKASIDE_LISTstruct _NPAGED_LOOKASIDE_LIST (sizeof = 80)!!!! ... 30 s truct _LIST_ENTRY ListEntry ... kd> 8047F8D0-30 8047F8D0-30Evaluate expression:??!! -2142766944 = 8047f8a0kd> lookaside 8047f8a0 lookaside 8047f8a0Lookaside "" @ 8047f8a0 "ObCi" Type = 0000 NonPagedPoolCurrent Depth = 2 Max Depth = 4Size = 48 Max alloc = 192AllocateMisses = 24 FreeMisses = 0TotalAllocates = 73 TotalFrees = 51Hit Rate = 67% Hit Rate = 100% kd>! strct NPAGED_LOOKASIDE_LIST 8047f8a0! strct NPAGED_LOOKASIDE_LIST 8047f8a0struct _NPAGED_LOOKASIDE_LIST (sizeof = 80) 00 struct _GENERAL_LOOKASIDE L 00 union _SLIST_HEADER ListHead
00 uint64 Alignment = 0064000281feeb88 00 struct _SINGLE_LIST_ENTRY Next 00 struct _SINGLE_LIST_ENTRY * Next = 81FEEB88 04 uint16 Depth = 0002 06 uint16 Sequence = 0064 08 uint16 Depth = 0004 0a uint16 MaximumDepth = 0100 0c uint32 TotalAllocates = 00000049 10 uint32 AllocateMisses = 00000018 10 uint32 AllocateHits = 00000018 14 uint32 TotalFrees = 00000033 18 uint32 FreeMisses = 00000000 18 uint32 FreeHits = 00000000 1c int32 Type = 00000000 20 uint32 Tag = 6943624f 24 uint32 Size = 00000030 28 function * Allocate = 80466C80 2c function * Free = 80467297 30 struct _LIST_ENTRY ListEntry 30 struct _LIST_ENTRY * Flink = 8047F930 34 struct _LIST_ENTRY * Blink = 80473378 38 uint32 LastTotalAllocates = 00000049 3c uint32 LastAllocateMisses = 00000018 3c uint32 LastAllocateHits = 00000018 40 uint32 Future [2] = 00000000 00000000 .... .... 48 uint32 Lock = 00000000 kd> dd ExNPagedLookasideListHead l 2dd ExNPagedLookasideListHead l 280473378 8047f8d0 eeffec90 // remember that we are from ExPagedLookasideListHead 804733 78 Start, when we see 80473378 //, it means that the chain has been looped.
kd> dd $ pl 2dd $ pl 28047f8d0 8047f930 80473378kd> 8047f930 814521f8 8047f8d0kd> 814521f8 81452198 8047f930kd> 81452198 80472130 814521f8kd> 80472130 8141b1b8 81452198kd> 8141b1b8 80473650 80472130kd> 80473650 804736b0 8141b1b8kd> 804736b0 80473530 80473650kd> 80473530 80473590 804736b0kd> 80473590 804735f0 80473530kd> 804735f0 804737b0 80473590kd> 804737b0 80475830 804735f0kd> 80475830 804756d0 804737b0kd> 804756d0 804758d0 80475830kd> 804758d0 80475770 804756d0kd> 80475770 8141a2f8 804758d0kd> 8141a2f8 81416d18 80475770kd> 81416d18 81416cb8 8141a2f8kd> 81416cb8 81416c58 81416d18kd> 81416c58 80480b30 81416cb8kd> 80480b30 fcd5c510 81416c58kd> fcd5c510 fcd5c1b0 80480b30kd> fcd5c1b0 fcd5c390 fcd5c510kd> fcd5c390 fcd5c290 fcd5c1b0kd> fcd5c290 fcd5c0f0 fcd5c390kd> fcd5c0f0 fcd1e9b0 fcd5c290kd> fcd1e9b0 fcd1ea00 fcd5c0f0kd> fcd1ea00 813d0618 fcd1e9b0kd> 813d0618 813cf3d8 fcd1ea00kd> 813cf3d8 813f6ef8 813d0618kd> 813f6ef8 813f6c58 813cf3d8kd> 813f6c58 8140c198 813f6ef8kd> 8140c198 8140cef8 813f6c58kd> 8140cef8 8140cc58 814 0c198kd> 8140cc58 8140c9b8 8140cef8kd> 8140c9b8 8140c6b8 8140cc58kd> 8140c6b8 813f5198 8140c9b8kd> 813f5198 813f53d8 8140c6b8kd> 813f53d8 fcccd430 813f5198kd> fcccd430 fcccd530 813f53d8kd> fcccd530 fcccd610 fcccd430kd> fcccd610 813c84b8 fcccd530kd> 813c84b8 f08915d0 fcccd610kd> f08915d0 f0325c10 813c84b8kd> f0325c10 f0325a30 f08915d0kd> f0325a30 f0325ff0 f0325c10kd> f0325ff0 f0325a90 f0325a30kd> f0325a90 f0325f70 f0325ff0kd> f0325f70 f03260f0 f0325a90kd> f03260f0 f03259d0 f0325f70kd> f03259d0 8132eb58 f03260f0kd> 8132eb58 812aa5f0 f03259d0kd> 812aa5f0 812aa640 8132eb58kd>
812aa640 812aa690 812aa5f0kd> 812aa690 812aa6e0 812aa640kd> 812aa6e0 812aa730 812aa690kd> 812aa730 812aa780 812aa6e0kd> 812aa780 f05283f0 812aa730kd> f05283f0 f0528450 812aa780kd> f0528450 812a7f98 f05283f0kd> 812a7f98 812a32e8 f0528450kd> 812a32e8 812a3338 812a7f98kd> 812a3338 812a50f8 812a32e8kd> 812a50f8 f05574b0 812a3338kd> f05574b0 f05572f0 812a50f8kd> f05572f0 f05576b0 f05574b0kd> f05576b0 f05573b0 f05572f0kd> f05573b0 f0557450 f05576b0kd> f0557450 f0557650 f05573b0kd> f0557650 f07fd150 f0557450kd> f07fd150 f07fd330 f0557650kd> f07fd330 ef093848 f07fd150kd> ef093848 ef05d910 f07fd330kd> ef05d910 810a6b38 ef093848kd> 810a6b38 810a6b88 ef05d910kd> 810a6b88 810a6bd8 810a6b38kd> 810a6bd8 810a6c28 810a6b88kd> 810a6c28 eeffeb50 810a6bd8kd> eeffeb50 eeffebf0 810a6c28kd> eeffebf0 eeffeba0 eeffeb50kd> eeffeba0 eeffec40 eeffebf0kd> eeffec40 eeffec90 eeffeba0kd> eeffec90 80473378 eeffec40kd> 80473378 8047f8d0 eeffec90 // we saw 80,473,378, represents the chain has a circulation of items LookasideList LookasideList items by 00 struct _SINGLE_LIST_ENTRY * Next Chain, chain together. The end of the chain is empty. The following is used to give an example.