Memory manager

!ca

Decode the control area of a section, with its segment and subsections.

!ca <control-area>

Also: ca

Shows the section, PFN, mapped-view, and user reference counts, the _MMSECTION_FLAGS that are set, and the backing file object and its name. It also shows the segment (PTE count, size, committed pages, and prototype PTEs) and, for each subsection, the base PTE, the PTE count, the starting sector, the sector count, and the protection. The command reads up to 1,024 subsections along NextSubsection, starting from the subsection after the control area, and stops at a subsection that points to a different control area. To find a control area, use the SectionObjectPointer of a file object or the Subsection of a VAD.

!filecache

Show the views that the cache manager has mapped, for each file.

!filecache

Also: filecache

Walks the VACB arrays (CcVacbArrays) to find the views in use, and groups the views by shared cache map. For each file, the command shows its name, the mapped 256 KB views, the pages of these views that are present in memory, the dirty pages, the file size, and the open count, with the file that has the most present data first. The summary shows the VACBs in use and free, and the bytes mapped and present. The command lists up to 1,024 files, and you can interrupt the walk.

!lookaside

List or decode GENERAL_LOOKASIDE caches.

!lookaside [address]

Also: lookaside

With no argument, the command walks the exported nonpaged and paged lookaside lists and detects cycles. With an address, it decodes only that entry.

!mdl

Decode a memory descriptor list and the page frames it describes.

!mdl <address> [pfn-count]

Also: mdl

The command shows the MDL header and the PFN array that follows it. The header fields are Next, Size, MdlFlags by MDL* name, Process, MappedSystemVa, StartVa, ByteCount, and ByteOffset. By default, the PFN count is the number of pages that ByteCount spans from ByteOffset, and a pfn-count overrides this value. In both cases, the count cannot be more than the slots that Size leaves after the header. If the Size, ByteOffset, or span of the header cannot describe an MDL, the command gives an error. The command does not follow Next, so for a chained MDL, run !mdl on the Next address.

!memusage

Show the system memory-use counters and the counters of a limited number of processes.

!memusage [process-limit]

The command uses validated memory-manager globals, KDBG fields, or recognized public getter code, and EPROCESS.Vm counters. It does not scan physical memory, and it does not walk all VADs.

!pfn

Decode an _MMPFN entry.

!pfn <pfn>
!pfn -a <physical-address>

Also: pfn

A plain value is a page-frame number. Use -a to read the value as a physical address.

!pool

Show the pool page that contains an address.

!pool <address>

Also: pool

!poolfind

Find pool blocks with a matching tag.

!poolfind <tag> [0|1]

Also: poolfind

The command reads the mapped pages of the pool ranges and the big-page table. On Windows 10 1803 and later, the pool ranges are the fixed regions in MiState.Vs.SystemVaRegions. On earlier builds, they come from MmNonPagedPoolStart and related symbols. The optional type selects nonpaged (0) or paged (1) pool. The scan stops after 1,024 matches, and you can interrupt it.

!poolused

Show pool tracker usage by tag.

!poolused [flags] [tag]

Also: poolused

The command adds up the usage from the tag table of each processor, which counts big allocations too; the big-page table is read only when those tables cannot be. Tags with no allocation outstanding are left out. The flags follow WinDbg: bit 1 (2) sorts by nonpaged bytes, bit 2 (4) sorts by paged bytes, and bit 0 (1) shows the alloc/free columns. The tag match is case-sensitive and supports * and ?.

!poolval

Check the block headers of the pool page that contains an address.

!poolval <address> [level]

Also: poolval

The command reports the page as VALID or INVALID, with the first inconsistency. The blocks of a classic pool page must make a chain from the start of the page to its end, in which the PreviousSize of each block matches the BlockSize of the block before it. Segment-heap pages (Windows 10 1903 and later) have no PreviousSize chain, so on these pages the inconsistency is a block whose BlockSize runs over the header of another block. The PoolType of a classic block must also identify the pool (paged or nonpaged) that holds the page. A level of 1 or more also lists all block headers. The command does not do the single-bit-error scan of WinDbg.

!pte

Show the page table entries for an address.

!pte <address>

Also: pte

!ptov

Find the virtual addresses in the current directory base that map a physical address.

!ptov <physical-address>

Also: ptov

The command walks the page tables in reverse and detects cycles in them. The walk stops after 32 mappings or 65,536 table pages. It works on AMD64 targets only.

!sysptes

Show system PTE usage from the memory manager’s bitmap allocators.

!sysptes [flags]

Also: sysptes

Windows 10 and later allocate system PTEs from _MI_SYSTEM_PTE_TYPE bitmap allocators in MiState. These allocators are Vs.SystemPteInfo (the SystemPtes region) and the system-view, non-cached-mapping, and kernel-stack allocators of SystemPtes. For each allocator, the command shows the VA range that it serves, TotalSystemPtes, TotalFreeSystemPtes, the PTEs in use, and PteFailures, and from the bitmap, the number of free blocks and the largest free block. The command reads all of the bitmap, up to 2^27 bits, a limit that only a corrupt SizeOfBitMap exceeds. If the free count from the bitmap differs from the counter, the target made an allocation between the reads or a processor holds PTEs in the allocator’s cache; the free count comes from the bitmap. Where the counters cannot be true of the bitmap (a total beyond it, a free count below zero or above the total, as on Windows 11 22631 ARM64), the allocator’s total and use are shown as unknown and left out of the summary, and !vm shows no system-PTE totals. All counts are in PTEs, and each bit of the system-view bitmap covers 16 PTEs. The flags follow WinDbg. 0x1 lists each free block with its first PTE, the address that it maps, and its length, up to 256 free blocks for each allocator. 0x4 (PTEs that map locked pages) needs the TrackPtes tracking of the kernel, and shows which allocators track but does not list the tracked mappings. The command ignores 0x2, 0x8, and 0x10, which select Windows 2000/XP/Vista lists that these allocators replaced. On a build without these allocators, the command gives an error.

!vm

Show virtual-memory statistics.

!vm [flags]

Also: vm

The command shows system memory, pool, PTE, page-file, and process usage. The flags follow WinDbg: bit 0 omits the per-process rows, and the command accepts bits 1, 2, and 3 but ignores them. If the command cannot read a counter, it still shows the other counters.

!vprot

Show the VirtualQuery data for a user address.

!vprot <address>

Also: vprot

The command shows the region, state, protection, and type of a user address, as VirtualQuery reports them. It looks up the address in the current process context, which you can select with .process /p <pid>. The VAD that holds the address gives AllocationBase, AllocationProtect, and Type, and the state and protection of each page come from its PTE. For a page without a PTE, they come from the VAD (private memory) or from its prototype PTE (a section view). RegionSize runs from the page of the address to the first page that differs. An address that is not in a VAD is MEM_FREE up to the next VAD. The scan stops after 262,144 page-table steps. On a user-mode minidump the command reads the region from the dump’s memory-info list, which records what VirtualQuery returned when the dump was written; RegionSize runs from the page of the address to the end of that region.

!vtop

Translate a virtual address with an explicit directory base.

!vtop <directory-base> <virtual-address>

Also: vtop

The command shows each page-table level and the final physical address. A directory base of zero uses the current context, and for a large page, the walk stops at its leaf level.