Profile custom allocator memory in Timing Captures

PIX Timing Captures can track allocations and frees from your custom memory allocators when your title records memory events with WinPixEventRuntime. Use this instrumentation when your title allocates memory through an allocator that PIX can't identify through system APIs such as VirtualAlloc or HeapAlloc.

Custom allocator events appear with the rest of the Timing Capture memory data. PIX shows the same data for your custom allocators that it shows for allocations made with VirtualAlloc or HeapAlloc, so you can inspect allocation activity in Range Details and include those allocations in memory analysis. For general memory analysis workflows, see Analyze memory usage in Timing Captures and Timing Captures Memory Layout.

Instrument your allocator

PIXRecordMemoryAllocationEvent and PIXRecordMemoryFreeEvent require WinPixEventRuntime version 1.0.230302001 or later.

Include pix3.h, make sure USE_PIX is defined, and record an event each time your allocator allocates or frees a block. Use:

The APIs take an allocator ID, base address, size, and metadata value. For the current signatures and parameter types, see Memory events in the WinPixEventRuntime API reference.

#define USE_PIX
#include <pix3.h>

void* TitleAllocate(size_t size, UINT64 metadata)
{
    void* allocation = AllocateFromTitleAllocator(size);
    if (allocation == nullptr)
    {
        return nullptr;
    }

    PIXRecordMemoryAllocationEvent(7, allocation, size, metadata);
    return allocation;
}

void TitleFree(void* allocation, size_t size, UINT64 metadata)
{
    if (allocation == nullptr)
    {
        return;
    }

    FreeFromTitleAllocator(allocation);
    PIXRecordMemoryFreeEvent(7, allocation, size, metadata);
}

Use a stable allocator ID for each allocator that you want to distinguish in PIX. PIX displays events from title-defined allocators as CustomAlloc N and CustomFree N, where N is the allocator ID that you pass to the WinPixEventRuntime memory event APIs.

Note

The memory event APIs are active when USE_PIX is active on a supported architecture. When USE_PIX isn't active, the Windows header provides inline no-op definitions for these APIs.

Capture custom allocator events

Before you start the Timing Capture, enable Custom allocator events in the Timing Capture options. This option is off by default.

If you use programmatic capture, set the CapturePixMemEvents field in PIXCaptureParameters::TimingCaptureParameters before calling PIXBeginCapture. For programmatic capture setup, see Programmatic capture.

Analyze custom allocator events

Open Range Details and set Item Type to Custom Memory Allocations. PIX lists the recorded custom allocation and free events with columns for:

  • Event name.
  • Address.
  • Size.
  • Unfreed size.
  • Metadata.
  • Time.
  • Thread.

Use the allocator selector in Range Details to show or hide individual custom allocators. PIX creates selector entries for title-defined allocator IDs and sorts them by ID.

The Allocation Stack Tree groups title-defined allocator memory by allocator under Title Allocators by Id. The allocator ID is the first parameter that you pass to PIXRecordMemoryAllocationEvent. Each custom allocator also uses the CustomAlloc N naming form in allocator summaries and memory-event names.