Evil Source
How memory works in Xbox 360 - Printable Version

+- Evil Source (http://evilsource.net)
+-- Forum: Consoles (http://evilsource.net/Forum-Consoles)
+--- Forum: Xbox (http://evilsource.net/Forum-Xbox)
+---- Forum: Xbox 360 (http://evilsource.net/Forum-Xbox-360)
+---- Thread: How memory works in Xbox 360 (/Thread-How-memory-works-in-Xbox-360)



How memory works in Xbox 360 - theDomo - 09-09-2019

How memory works in Xbox 360:
The Xbox 360 has a 64-bit CPU. The hypervisor runs in 64-bit mode, controlling security related features; the supervisor (aka. the kernel and the titles) runs in 32-bit mode. The Xbox 360 has 512MB GDDR3 RAM. Special Advanced DevKits (ADKs) have 1GB of GDDR3 RAM.

Memory address space:
The first thing to understand about memory is the memory address space. In Xbox 360, we have 3 of them.

Physical memory address space:
This is the simplest of the three, yet the farthest from the programs running on Xbox 360.

Physical memory address is 32 bit, spans across 4GB. It points to any storage attached to the CPU’s Front Side Bus (FSB). This includes both physical memory (usually 512MB, or 1GB for ADKs) and MMIO devices, such as GPU MMIO, North Bridge MMIO, South Bridge MMIO and PCI space.

The address space is carved like this:
Quote:
        ----------------------------------------------------------------------------------------------------
        |                                  0x00000000 - 0xFFFFFFFF (4GB)                                   |
        |                               Physical Memory Address Space                                      |
        |--------------------------------------------------------------------------------------------------|
        | 0x00000000 - 0x3FFFFFFF |                                               | 0xC0000000 - 0xFFFFFFFF|
        |       (1GB)             |                  Unused                       |          (1GB)         |
        |    Physical RAM         |                                               |          MMIO          |
        |--------------------------------------------------------------------------------------------------|
        |0x00000000 -|0x20000000 -|                                               | PCI Configuration      |
        |0x1FFFFFFF  |0x3FFFFFFF  |                                               | Configured MMIO devices|
        |  (512MB)   | (512MB)    |                                               | SB Flash ROM XIP       |
        |Physical RAM|ADK Physical|                                               |                        |
        |            |   RAM      |                                               |                        |
        ----------------------------------------------------------------------------------------------------

Real memory address space:
Real memory is mostly mapping of the physical memory, but with some very interesting modifications.
Real memory address is 64 bit, but only the lower 42 bit is used. Real memory address is only directly accessible in hypervisor. The supervisor can only access 32 bit virtual memory address, discussed in the next section.

The 2 most significant bit of the 42 bit address forms a table. Since these 2 bits correspond to 1TB in address, they are usually referred to as the TeraByte (TB) bits.
        ---------------------------------------------------------------------------------------------
        | TB  | Address to                                                                          |
        |-------------------------------------------------------------------------------------------|
        |  0  | Direct map of physical memory                                                       |
        |-------------------------------------------------------------------------------------------|
        |  1  | Encrypted and integrity protected mapping of physical memory                        |
        |-------------------------------------------------------------------------------------------|
        |  2  | SoC MMIO registers on the CPU                                                       |
        |-------------------------------------------------------------------------------------------|
        |  3  | Encrypted mapping of physical memory                                                |
        ---------------------------------------------------------------------------------------------

TB=0: mapping of physical memory:
When TB=0, the low 32 bit of the address maps directly to the physical address. The middle 8 bits must be 0.

TB=1: Encrypted and integrity protected mapping of physical memory

TB=3: Encrypted mapping of physical memory
In these two TB range, the low 30 bits of the address maps to the physical address of the 1GB RAM, and the middle 10 are used as parameters to the encryption and integrity protection.

The encryption / integrity protection happens at the L2 cache level. When memory is fetched from RAM to L2, the memory is decrypted and integrity checked; when memory is flushed from L2 to RAM, the memory is encrypted and the integrity hash is calculated and preserved.
This means that everything that runs on the CPU, as long as they have the correct real address, operates in a decrypted view of these memory; but everything that runs outside the CPU will view them as encrypted garbage. This prevents physical memory attacks such as DMA attacks.

TB=2: SoC MMIO registers on the CPU:
This range of real address points to the System on Chip registers of the Xbox 360 CPU. The address is defined by the CPU and controls various aspects of how CPU works, such as the cryptographic parameters for TB=1/TB=3, voltage and frequency of the CPU, hardware Pseudo Random Number Generator, and FSB. Most access to TB=2 are strictly limited in hypervisor mode.

Virtual address space
And finally, the virtual address space is the one that everyone interacts most, and yet the most complicated address space in Xbox 360.
A virtual address is 32 bit. All supervisor code can only access this virtual address space.
In theory, a virtual address can point to anywhere in the real address space. Unlike other CPU architectures in which the CPU can directly look up the page table to translate a virtual address to real address, the Xbox 360 CPU relies solely on the Translate Look-aside Buffer (TLB) to perform the virtual to real translation.
Xbox 360 CPU has 1024 TLB entries. They operate as a cache in some LRU fashion. If a virtual to real translation misses the TLB, a trap is generated and the hypervisor will install a TLB entry for the corresponding virtual address and resume the interrupted code. This means it would be a relatively big performance hit when TLB misses, but it also means the virtual to real translation doesn’t need to be based on one uniform page table, and gives the software all the flexibility to map virtual address to real address in any fashion. And that is exactly how Xbox 360 operates, with a complex virtual memory mapping.

        ---------------------------------------------------------------------------------------------------
        |               | 0xE0000000- | The virtual address maps continuously to real address 0 to 512MB, |
        |               | 0xFFFFFFFF  | shifted by 1 4KB page. The shift was to work around a CPU bug.    |
        |               |  4KB Page   |                                                                   |
        |               |  (512MB)    |                                                                   |
        |               |---------------------------------------------------------------------------------|
        |               | 0xC0000000- |                                                                   |
        |  0xA0000000-  | 0xDFFFFFFF  |                                                                   |
        |  0xFFFFFFFF   |  16MB Page  |                                                                   |
        | Physical Range|  (512MB)    |                                                                   |
        |   (1.5GB)     |-------------| The virtual address maps continuously to real address 0 to 512MB. |
        |               | 0xA0000000- |                                                                   |
        |               | 0xBFFFFFFF  |                                                                   |
        |               |  64KB Page  |                                                                   |
        |               |  (512MB)    |                                                                   |
        |-------------------------------------------------------------------------------------------------|
        |               |             | 0x92000000-0x9FFFFFFF                                             |
        |               | 0x90000000- | Title 4K Image (224MB)                                            |
        |               | 0x9FFFFFFF  |-------------------------------------------------------------------|
        |               |  4KB Page   | 0x90000000-0x91FFFFFF                                             |
        |  0x80000000-  |  (256MB)    | System 4K Image (32MB)                                            |
        |  0x9FFFFFFF   |---------------------------------------------------------------------------------|
        |  Image Range  |             | 0x8C000000-0x8FFFFFFF                                             |
        |    (512MB)    |             | Other Encrypted memory (64MB)                                     |
        |               | 0x80000000- |-------------------------------------------------------------------|
        |               | 0x8FFFFFFF  | 0x82000000-0x8BFFFFFF                                             |
        |               |  64KB Page  | Title 64KB Image (160MB)                                          |
        |               |  (256MB)    |-------------------------------------------------------------------|
        |               |             | 0x80000000-0x81FFFFFF                                             |
        |               |             | System 64KB Image (32MB)                                          |
        |-------------------------------------------------------------------------------------------------|
        |               |             |             | 0x7A000000-0x7FFFFFFF                               |
        |               |             | 0x78000000- | System 64KB PTE Memory (96MB)                       |
        |               |             | 0x7FFFFFFF  |-----------------------------------------------------|
        |               | 0x40000000- | System 64KB | 0x78000000-0x79FFFFFF                               |
        |               | 0x7FFFFFFF  |  (128MB)    | System 64KB VAD Memory (32MB)                       |
        |               |  64KB Page  |-------------------------------------------------------------------|
        |               |   (1GB)     |             | 0x70000000-0x77FFFFFF                               |
        |               |             | 0x40000000- | Title 64KB PTE Memory (128MB)                       |
        |               |             | 0x77FFFFFF  |-----------------------------------------------------|
        |               |             | Title 64KB  | 0x40000000-0x6FFFFFFF                               |
        |  0x00000000-  |             |  (896MB)    | Title 64KB VAD Memory (768MB)                       |
        |  0x7FFFFFFF   |---------------------------------------------------------------------------------|
        | Virtual Range |             |             | 0x3A000000-0x3FFFFFFF                               |
        |    (2GB)      |             | 0x38000000- | System 4KB PTE Memory (96MB)                        |
        |               |             | 0x3FFFFFFF  |-----------------------------------------------------|
        |               |             | System 4KB  | 0x38000000-0x39FFFFFF                               |
        |               | 0x00000000- |  (128MB)    | System 4KB VAD Memory (32MB)                        |
        |               | 0x3FFFFFFF  |-------------------------------------------------------------------|
        |               |  4KB Page   | 0x00000000- | 0x30000000-0x37FFFFFF                               |
        |               |   (1GB)     | 0x37FFFFFF  | Title 4KB PTE Memory (128MB)                        |
        |               |             | Title 4KB   |-----------------------------------------------------|
        |               |             |  (896MB)    | 0x00000000-0x2FFFFFFF                               |
        |               |             |             | Title 4KB VAD Memory (768MB)                        |
        ---------------------------------------------------------------------------------------------------

Virtual Range
This range of memory maps to unencrypted real address. Contiguous virtual address does not necessarily map to contiguous real address.
Two kinds of virtual address exist. VAD memory and PTE memory.
VAD memory corresponds to allocations made by VirtualAlloc. The name VAD represents Virtual Address Descriptor, a tree based data structure used internally by VirtualAlloc.
PTE memory corresponds to memory allocated by the kernel, for usage in pool, kernel thread stack, etc. The name PTE memory comes from the allocation of PTE memory being controlled directly by the PTEs, as opposed to VADs in VAD memory.
Practically, the difference between VAD memory and PTE memory is that VAD memory can be reserved and committed separately, thanks to the VAD data structure; while allocation of PTE memory means the pages are inherently committed during allocation. Also PTE memory can be allocated as cache-inhibited-write-through or cache-inhibited-write-combined in addition to cached, while VAD memory can only be cached.

Image Range
This range of memory can map to encrypted real address (TB=1 or 3), in addition to TB 0 real address. Contiguous virtual address does not necessarily map to contiguous real address.
The management of the image range is strictly performed by the hypervisor. The supervisor has no control over the management of image range. The hypervisor manages the image range through an Image PTE table residing in the hypervisor. The Image PTE table consists of Image PTEs describing pages in 64KB granularity. This fits nicely for 64KB image pages in the 0x80000000 range. For the 4KB image pages in the 0x90000000 range, however, an additional nibble array is used by the hypervisor to describe the access attributes (RO, RW or Execute) of each 4KB page within the 64KB pages. This is why allocation of image range memory can only be based on 64KB boundary, even though memory pages in the 0x90000000 Range can have different access attributes on each 4KB page.

Physical Range
Notice the wording “Physical Range”, not physical address. Being in the physical range, the address here is still virtual address. This range of memory maps contiguously to unencrypted real address. So it is easy to calculate the real/physical address from the virtual address – just mask out the low 29 bits. Also since the corresponding real/physical address contains only 29 bits, they can only address the low 512MB of the physical RAM. They can’t address the high 512MB physical RAM in ADK.

Page Size
Three possible page sizes exist on Xbox 360: 4KB, 64KB and 16MB. One TLB entry corresponds to one page, and memory within one page are guaranteed to be really/physically contiguous. Given the limited number of TLB entries, the larger the page size is, the less TLBs are required to map a given amount of memory, which reduces TLB misses. On the other hand, the larger the page size is, the more memory is wasted at the last page of each allocation. So it is a balance between performance and memory usage when choosing the page size.
Practically, the kernel, XAM and most title executables use 64KB page, while all other XAM DLLs use 4KB page. All system heaps use 64KB pages.

Page Tables?
Ignoring TLBs, which acts as a cache so only changing performance but not logic, the CPU conceptually asks directly the hypervisor on how to translate a virtual address to a real address. The hypervisor, in turn, relies on several data structures to provide the answer, depending on the type of the virtual address.

        -----------------------------------------------------------------------------------------------
        | Virtual 4KB   | MM_PAGE_TABLES_BASE: page directory + page table                            |
        |---------------------------------------------------------------------------------------------|
        | Virtual 64KB  | MM_64KB_PAGE_TABLE_PHYSICAL_PAGE: flat 64KB page table                      |
        |---------------------------------------------------------------------------------------------|
        | Image 4KB     | MM_HV_PTE_PHYSICAL_PAGE: flat 64KB page table + 4KB page nibble array       |
        |---------------------------------------------------------------------------------------------|
        | Image 64KB    | MM_HV_PTE_PHYSICAL_PAGE: flat 64KB page table                               |
        |---------------------------------------------------------------------------------------------|
        | Physical 4KB  | MmPfnDatabase: 4KB page PFN array                                           |
        |---------------------------------------------------------------------------------------------|
        | Physical 64KB | MmPhysical64KBMappingTable: 64KB page nibble array                          |
        |---------------------------------------------------------------------------------------------|
        | Physical 16MB | MmPdeDatabase: 16MB page nibble array                                       |

System vs. Title process
Xbox 360 runs two processes, the system process and the title process. Although they are called processes, they share the same virtual address space, i.e., they don’t have memory protection against each other. This is why on the table above, each virtual address range is split between title and system process.
During a title reboot, all the title process’s memory ranges are torn down and reset to unallocated, while all the system process’s memory ranges remain intact.
This inherently brings an issue: if a system process thread tries to access a piece of memory in the title address range, it is dangerous and can potentially lead to crash, as the title process can be torn down at any time (e.g. triggered by the user ejecting the game disc). Thus the preferred way to pass message from the title process to the system process is through the XAM message system. On the other hand, the only safe way to access title memory from a system process (which should be limited to an absolute minimum), is to register a title termination notification and do proper clean up there.

The physical memory usage between the system process and the title process are hard limited to 32MB + 480 MB. This is done through the memory manager structure known as the PFN Region. The System PFN region contains the low 32MB of physical pages, and the Title PFN region contains the high 480MB of physical pages. Whenever a physical page is required for committing to a virtual address, the PFN region of the corresponding process is queried for obtaining the physical page. A kernel debugger extension !memusage lists the physical page usage summary of the two PFN regions.


Cache attributes
Three cache attributes are exposed from the memory manager: cached, cache-inhibited-write-through (PAGE_NOCACHE), and cache-inhibited-write-combined (PAGE_WRITECOMBINE). The XDK has the best description of the latter two:

Non-cached Reads
Non-cached reads from memory take about as long as L2 misses. This makes them extremely expensive, so they are best avoided. Reading from non-cacheable memory (allocated with PAGE_NOCACHE or PAGE_WRITECOMBINE) should not be necessary on Xbox 360.
Non-cacheable Writes
Non-cacheable writes go through a separate path from cacheable writes. Writes going to memory allocated with PAGE_NOCACHE are sent over the front-side bus one at a time, giving extremely poor write performance. PAGE_NOCACHE should not be used.
Writes going to memory allocated with PAGE_WRITECOMBINE are collected together using separate store-gather buffers. The non-cacheable write-combined store-gather buffers are not as flexible as the cacheable store-gather buffers from cacheable writes. Non-cacheable store-gathering requires that writes be properly aligned, with a length of four bytes or greater, and the data must be written sequentially, with no gaps, and no duplicate writes to the same address. If these rules are followed, each core can efficiently gather stores to two non-cacheable streams. If these rules are not followed, then write performance will be reduced.
Non-cacheable write-combined writes are useful for data that is destined for the GPU, since these writes avoid the need to flush data to memory after writing it. Non-cacheable write-combined writes avoid wasting space in the L2 cache on data that will never be read. They also avoid some of the L2 bottlenecks that can occur when all three cores are heavily using the L2 cache. Non-cacheable write-combined writes increase the total amount of write bandwidth available to the Xbox 360 CPU. However, non-cacheable memory should not be used for data that you will need to read, including read-modify-write updates of data, because the performance on reads will be very poor.

Heaps:
The most frequent memory an application uses is heap memory. On Xbox 360, most system software uses the RtlHeap, which is well documented in MSDN http://msdn.microsoft.com/en-us/library/ff552159.aspx.

XAM on startup creates several heaps for different XAM app usage. These heaps can be examined by a kernel debugger extension !xamalloc. 

Xbox 360 also has a page heap implementation, which can be used in both the system process (XAM) or title process (Dash or other titles). Using the page heap requires an ADK with 1GB of physical RAM, because page heap uses a lot more memory than RtlHeap.

Heap memory layout

0: kd> !xamexts.xamalloc -r
Type From To SizeHex SizeDec


  Wrkspace (DASH) 00010000 00110000 00100000
  Wrkspace 00010000 00070000 00060000 384.00 KB
     Perma 78000000 781f0000 001f0000   1.94 MB
       XMP 781f0000 783f0000 00200000   2.00 MB
        UI 783f0000 785a0000 001b0000   1.69 MB
   UIRunti 785a0000 788d0000 00330000   3.19 MB
  ChalResp 788d0000 788f0000 00020000 128.00 KB
  Encryptd 8c000000 8c020000 00020000 128.00 KB
      IPTV 788f0000 78940000 00050000 320.00 KB
  Messengr 78940000 78980000 00040000 256.00 KB
      Comm 00000000 00000000 00000000   0.00 B 


     Total -        -        00a00000  10.00 MB
0: kd> dt -a10 xam!xamheaps

@ 81d3d028
   +0x000 HeapId           : 0 ( XAMALLOC_HEAP_WORKSPACE )
   +0x004 Handle           : 0x00010000 Void
   +0x008 BaseAddress      : 0x00010000 Void
   +0x00c ReserveSize      : 0x60000
   +0x010 AllocatedMemory  : 0y1
   +0x010 NoAccess         : 0y0
   +0x010 Encrypted        : 0y0
   +0x010 Unmountable      : 0y0
   =815f0000 PageHeap         : 4d
   +0x014 MemoryRegionType : 1 ( MemoryRegionTitle )
   +0x018 XamAppCounters   : [16] AllocationCounter
   +0x158 CreateFooters    : 0n0
   +0x15c LastKnownFreeSpace : 0x5f370
   +0x160 LowestFreeSpaceWarned : 0xffffffff
   +0x164 Utilization      : 0 
   +0x168 ObjectLock       : _RTL_CRITICAL_SECTION

@ 81d3d1ac
   +0x000 HeapId           : 1 ( XAMALLOC_HEAP_PERMANENT )
   +0x004 Handle           : 0x78000000 Void
   +0x008 BaseAddress      : 0x78000000 Void
   +0x00c ReserveSize      : 0x1f0000
   +0x010 AllocatedMemory  : 0y1
   +0x010 NoAccess         : 0y0
   +0x010 Encrypted        : 0y0
   +0x010 Unmountable      : 0y0
   =815f0000 PageHeap         : 4d
   +0x014 MemoryRegionType : 2 ( MemoryRegionSystem )
   +0x018 XamAppCounters   : [16] AllocationCounter
   +0x158 CreateFooters    : 0n0
   +0x15c LastKnownFreeSpace : 0xe2d80
   +0x160 LowestFreeSpaceWarned : 0xffffffff
   +0x164 Utilization      : 98.507164 
   +0x168 ObjectLock       : _RTL_CRITICAL_SECTION

@ 81d3d330
   +0x000 HeapId           : 2 ( XAMALLOC_HEAP_XMP )
   +0x004 Handle           : 0x781f0000 Void
   +0x008 BaseAddress      : 0x781f0000 Void
   +0x00c ReserveSize      : 0x200000
   +0x010 AllocatedMemory  : 0y1
   +0x010 NoAccess         : 0y0
   +0x010 Encrypted        : 0y0
   +0x010 Unmountable      : 0y0
   =815f0000 PageHeap         : 4d
   +0x014 MemoryRegionType : 2 ( MemoryRegionSystem )
   +0x018 XamAppCounters   : [16] AllocationCounter
   +0x158 CreateFooters    : 0n0
   +0x15c LastKnownFreeSpace : 0x12e170
   +0x160 LowestFreeSpaceWarned : 0xffffffff
   +0x164 Utilization      : 98.10861206 
   +0x168 ObjectLock       : _RTL_CRITICAL_SECTION

@ 81d3d4b4
   +0x000 HeapId           : 3 ( XAMALLOC_HEAP_UI )
   +0x004 Handle           : 0x783f0000 Void
   +0x008 BaseAddress      : 0x783f0000 Void
   +0x00c ReserveSize      : 0x1b0000
   +0x010 AllocatedMemory  : 0y1
   +0x010 NoAccess         : 0y0
   +0x010 Encrypted        : 0y0
   +0x010 Unmountable      : 0y1
   =815f0000 PageHeap         : 4d
   +0x014 MemoryRegionType : 2 ( MemoryRegionSystem )
   +0x018 XamAppCounters   : [16] AllocationCounter
   +0x158 CreateFooters    : 0n0
   +0x15c LastKnownFreeSpace : 0x1a7d60
   +0x160 LowestFreeSpaceWarned : 0xffffffff
   +0x164 Utilization      : 87.84689331 
   +0x168 ObjectLock       : _RTL_CRITICAL_SECTION

@ 81d3d638
   +0x000 HeapId           : 4 ( XAMALLOC_HEAP_UIRUNTIME )
   +0x004 Handle           : 0x785a0000 Void
   +0x008 BaseAddress      : 0x785a0000 Void
   +0x00c ReserveSize      : 0x330000
   +0x010 AllocatedMemory  : 0y1
   +0x010 NoAccess         : 0y0
   +0x010 Encrypted        : 0y0
   +0x010 Unmountable      : 0y0
   =815f0000 PageHeap         : 4d
   +0x014 MemoryRegionType : 2 ( MemoryRegionSystem )
   +0x018 XamAppCounters   : [16] AllocationCounter
   +0x158 CreateFooters    : 0n0
   +0x15c LastKnownFreeSpace : 0x1b4310
   +0x160 LowestFreeSpaceWarned : 0xffffffff
   +0x164 Utilization      : 90.29540253 
   +0x168 ObjectLock       : _RTL_CRITICAL_SECTION

@ 81d3d7bc
   +0x000 HeapId           : 5 ( XAMALLOC_HEAP_CHALRESP )
   +0x004 Handle           : 0x788d0000 Void
   +0x008 BaseAddress      : 0x788d0000 Void
   +0x00c ReserveSize      : 0x20000
   +0x010 AllocatedMemory  : 0y1
   +0x010 NoAccess         : 0y0
   +0x010 Encrypted        : 0y0
   +0x010 Unmountable      : 0y0
   =815f0000 PageHeap         : 4d
   +0x014 MemoryRegionType : 2 ( MemoryRegionSystem )
   +0x018 XamAppCounters   : [16] AllocationCounter
   +0x158 CreateFooters    : 0n0
   +0x15c LastKnownFreeSpace : 0x1f370
   +0x160 LowestFreeSpaceWarned : 0xffffffff
   +0x164 Utilization      : 0 
   +0x168 ObjectLock       : _RTL_CRITICAL_SECTION

@ 81d3d940
   +0x000 HeapId           : 6 ( XAMALLOC_HEAP_ENCRYPTED )
   +0x004 Handle           : 0x8c000000 Void
   +0x008 BaseAddress      : 0x8c000000 Void
   +0x00c ReserveSize      : 0x20000
   +0x010 AllocatedMemory  : 0y1
   +0x010 NoAccess         : 0y0
   +0x010 Encrypted        : 0y1
   +0x010 Unmountable      : 0y0
   =815f0000 PageHeap         : 4d
   +0x014 MemoryRegionType : 2 ( MemoryRegionSystem )
   +0x018 XamAppCounters   : [16] AllocationCounter
   +0x158 CreateFooters    : 0n0
   +0x15c LastKnownFreeSpace : 0xf370
   +0x160 LowestFreeSpaceWarned : 0xffffffff
   +0x164 Utilization      : 94.99650574 
   +0x168 ObjectLock       : _RTL_CRITICAL_SECTION

@ 81d3dac4
   +0x000 HeapId           : 7 ( XAMALLOC_HEAP_MESSENGER )
   +0x004 Handle           : 0x788f0000 Void
   +0x008 BaseAddress      : 0x788f0000 Void
   +0x00c ReserveSize      : 0x50000
   +0x010 AllocatedMemory  : 0y1
   +0x010 NoAccess         : 0y0
   +0x010 Encrypted        : 0y0
   +0x010 Unmountable      : 0y0
   =815f0000 PageHeap         : 4d
   +0x014 MemoryRegionType : 2 ( MemoryRegionSystem )
   +0x018 XamAppCounters   : [16] AllocationCounter
   +0x158 CreateFooters    : 0n0
   +0x15c LastKnownFreeSpace : 0x4ecc0
   +0x160 LowestFreeSpaceWarned : 0xffffffff
   +0x164 Utilization      : 33.29951477 
   +0x168 ObjectLock       : _RTL_CRITICAL_SECTION

@ 81d3dc48
   +0x000 HeapId           : 8 ( XAMALLOC_HEAP_COMMUNITY )
   +0x004 Handle           : 0x78940000 Void
   +0x008 BaseAddress      : 0x78940000 Void
   +0x00c ReserveSize      : 0x40000
   +0x010 AllocatedMemory  : 0y1
   +0x010 NoAccess         : 0y0
   +0x010 Encrypted        : 0y0
   +0x010 Unmountable      : 0y0
   =815f0000 PageHeap         : 4d
   +0x014 MemoryRegionType : 2 ( MemoryRegionSystem )
   +0x018 XamAppCounters   : [16] AllocationCounter
   +0x158 CreateFooters    : 0n0
   +0x15c LastKnownFreeSpace : 0x392f0
   +0x160 LowestFreeSpaceWarned : 0xffffffff
   +0x164 Utilization      : 88.1661911 
   +0x168 ObjectLock       : _RTL_CRITICAL_SECTION

@ 81d3ddcc
   +0x000 HeapId           : cccc ( XAMALLOC_HEAP_UNINITIALIZED )
   +0x004 Handle           : (null) 
   +0x008 BaseAddress      : (null) 
   +0x00c ReserveSize      : 0
   +0x010 AllocatedMemory  : 0y0
   +0x010 NoAccess         : 0y0
   +0x010 Encrypted        : 0y0
   +0x010 Unmountable      : 0y0
   =815f0000 PageHeap         : 4d
   +0x014 MemoryRegionType : 0 ( MemoryRegionThread )
   +0x018 XamAppCounters   : [16] AllocationCounter
   +0x158 CreateFooters    : 0n0
   +0x15c LastKnownFreeSpace : 0
   +0x160 LowestFreeSpaceWarned : 0xffffffff
   +0x164 Utilization      : 0 
   +0x168 ObjectLock       : _RTL_CRITICAL_SECTION