PerfView Documentation

repository·main·Indexed 26 days ago

https://github.com/microsoft/perfview

PerfView is a free performance analysis tool for Windows optimized for .NET runtime performance investigation. It enables developers to isolate CPU and memory issues using ETW and EventPipe data. The tool is built upon the Microsoft.Diagnostics.Tracing.TraceEvent library, which can also be used for programmatic trace manipulation.

Tokens
27.5K
Snippets
32
Records
127
Agent score
87%

What's inside PerfView

  1. Overview of PerfView

    main
    PerfView is a free performance-analysis tool designed to isolate CPU and memory-related performance issues on Windows. It features specialized capabilities for investigating performance issues in code written for the .NET runtime and provides limited support for analyzing data collected on Linux machines.
  2. Understand PerfView code organization

    main

    The repository is organized into several key functional areas:

    • PerfView: The main GUI application.
      • StackViewer: GUI for 'stacks' views.
      • EventViewer: GUI for 'events' views.
      • Dialogs: GUI for various dialog boxes.
      • Memory: Code for memory investigations (e.g., Graph and MemoryGraph for GC heaps).
      • MainWindow: The initial launch window for file selection or data collection.
    • TraceEvent: The core library used to decode Event Tracing for Windows (ETW) data.
    • ETWClrProfiler*: Native code (32/64 bit) implementing the CLR Profiler API to trace object allocations and .NET method calls.
    • HeapDump*: Standalone executables (32/64 bit) for dumping the GC heap using Microsoft.Diagnostics.Runtime APIs.
    • Global: An example project demonstrating the PerfView extensibility mechanism.
  3. Understand the NetTrace File Format (Version 6)

    main

    NetTrace is a binary file format (typically using the *.nettrace extension) designed for efficient streaming of profiling or logging traces. It consists of a small header followed by a sequence of serialized blocks. The format is optimized for high throughput (millions of events per second) and low file size.

    Data is organized into five primary tables:

    • Event Table: Represents individual events.
    • Metadata Table: Stores event types (names, IDs, and field schemas).
    • Stack Table: Stores stack traces (sequences of instruction pointers).
    • Thread Table: Stores thread information (OS thread/process IDs, names).
    • Label List Table: Stores arbitrary key/value labels (e.g., correlation IDs).

    To resolve a single event, a reader must fetch the event row and then resolve its references to the metadata, stack, thread, and label list rows. These referenced rows must have appeared in blocks earlier in the file.

  4. Understand the EventPipe NetPerf Format

    main

    The NetPerf format (typically .netperf files) is a serialization of objects used by the .NET Core runtime for OS-independent logging (similar to ETW on Windows). It is designed to be simple, extensible, and streamable.

    Key Format Assumptions:

    • Primitive Types: Uses little-endian (least significant byte first) for byte, short, int, and long.
    • Strings: Emitted as a 4-byte integer (length) followed by the UTF8 encoding.
    • StreamLabels: Uses 32-bit numbers for position references (limiting references to 4GB).
    • Compression: The format is tuned for 'in-place' memory use and assumes compression is applied to the stream as a whole externally.
    • Alignment: The stream is byte-aligned by default, though specific objects may choose to align their data.
  5. Understand the ETWClrProfiler Project Structure

    main

    The ETWClrProfiler project implements a .NET Profiler API via a Dynamic Link Library (DLL). Key components include:

    • Profiler Implementation: The core logic implementing the .NET Profiler API is located in CorProfilerTracer.cpp. The Initialize method is the entry point for the profiler.
    • Event Schema: The schema for ETW (Event Tracing for Windows) events is defined in ETWClrProfiler.man.
    • COM Identity: The COM GUID used by the profiler is defined in ComInfrastructure.cpp.
    • Logging: Logger.* routines are debug-only utilities used for logging to a file.
    • Generated Headers: ETWClrProfiler.h is a generated file derived from the manifest. It is compiled using MC.EXE (see Stdafx.h for regeneration instructions).
  6. Understand the TraceEvent Library Architecture

    main

    The TraceEvent library is a .NET NuGet package designed to control and consume strongly typed Event Tracing for Windows (ETW) events. It works alongside System.Diagnostics.Tracing.EventSource to create an end-to-end semantic logging system.

    The architecture consists of three primary components:

    1. Event Session (Microsoft.Diagnostics.Tracing.TraceEventSession): Controls the logging process. It can start/stop providers, control verbosity, and route data to files or directly to the session for real-time processing.
    2. Event Provider (Microsoft.Diagnostics.Tracing.EventSource): The component integrated into the application being monitored. It calls logging APIs to emit events.
    3. Event Consumer (Microsoft.Diagnostics.Tracing.TraceEventSource): Processes data from files or sessions to generate statistics or alerts.

    Key Characteristics:

    • Strongly Typed (Semantic): Events follow a schema (manifest) defining names, types, and metadata, making processing more efficient and less fragile than string-based logging.
    • Asynchronous: Logging is a 'fire and forget' operation. Events are written to a buffer, allowing the application to continue immediately. This ensures high scalability and minimal impact on application performance, though it introduces the possibility of lost events if the consumer cannot keep up with the provider volume.
  7. Understand the TraceEvent architecture components

    main

    The TraceEvent library follows a specific pipeline for processing ETW data:

    1. TraceEventSession: Used to start new ETW sessions, enable providers, and direct output.
    2. ETW Providers: Sources of data, such as the Windows OS Kernel, .NET/JScript Runtimes, or custom System.Diagnostics.Tracing.EventSource providers.
    3. ETWTraceEventSource: The component that hooks into the event stream (either a live session or an ETL file).
    4. TraceEventParser: Converts unparsed events from the source into strongly typed objects.
      • Static Parsers: Efficient, compile-time parsers (e.g., built-in parsers or those generated via TraceParserGen).
      • Dynamic Parsers: Runtime parsers (e.g., DynamicTraceEventParser, RegisteredTraceEventParser, WPPTraceEventParser) used when schemas are unknown at compile time.
    5. Subscription: You subscribe to C# events provided by the parser.
    6. ETWTraceEventSource.Process(): The method that must be called to begin the processing loop and trigger callbacks.
  8. Understand the EventPipe (.nettrace) File Format

    main

    EventPipe is the OS-independent logging mechanism used by the .NET Core runtime (similar to ETW on Windows). Files are conventionally saved with the .nettrace extension. The format is designed to be simple, extensible, and streamable, utilizing the FastSerialization library conventions.

    Core Assumptions:

    • Primitive Types: Little-endian (byte, short, int, long).
    • Strings: Encoded as a 4-byte integer length prefix followed by UTF8 bytes.
    • Alignment: The stream is byte-aligned by default, though specific objects may choose to align data for efficiency.
  9. Debug EventSource authoring errors

    main

    Errors in EventSource (like duplicate event IDs) are often swallowed by the runtime, making them hard to detect. Use these techniques to diagnose them:

    1. Use the EventSource NuGet package: The Microsoft.Diagnostics.Tracing.EventSource package provides compile-time warnings for common errors.
    2. Run with the provider enabled constantly: Use PerfView to start a circular logging session for your provider so you can catch exceptions immediately:
      PerfView /CircularMB=10 /OnlyProviders:*Microsoft-Demos-MySource start
      Then, in your debugger, enable stopping on any thrown CLR exception (Debug $\rightarrow$ Exceptions).
    3. Check ConstructionException: In your DEBUG code, explicitly check and throw the ConstructionException property:
      if (MySource.ConstructionException != null)
        throw MySource.ConstructionException;
    4. Inspect Exceptions in PerfView: Even if swallowed by the runtime, the exceptions often appear as Exceptions events within PerfView.
    PerfView /CircularMB=10 /OnlyProviders:*Microsoft-Demos-MySource start
  10. Install the Microsoft.Diagnostics.Tracing.TraceEvent library

    main

    The TraceEvent library is a NuGet package used to collect and process event data, specifically designed for parsing Event Tracing for Windows (ETW) events. It is the engine behind PerfView's data manipulations.

    Compatibility:

    • .NET Desktop: v4.6.2 and up
    • .NET / .NET Core: netstandard2.0 and up
    • Platform: While parts of the library work on Linux, the ETW-related functionality requires Windows.

    Installation:

    1. Create a .NET project (.NET or .NET Desktop).
    2. Right-click on your project in your IDE.
    3. Select Manage NuGet Packages.
    4. Search for and install Microsoft.Diagnostics.Tracing.TraceEvent.
  11. Maintain backward and forward compatibility in EventPipe formats

    main

    When updating the EventPipe file format, follow these patterns to ensure compatibility:

    Backward Compatibility (New readers, old writers)

    To allow new readers to process old files:

    1. Increment the Version number for the Trace Type.
    2. Set the MinimumReaderVersion to the new version number.
    3. Implement logic in the reader to check the object's Version. If the version is less than the new version, use the legacy reading logic; otherwise, use the new format logic.

    Forward Compatibility (Old readers, new writers)

    To allow old readers to process new files without crashing:

    • Use Tagged values: Add new fields to an object using tagged data (e.g., tags for bool, byte, short, int, long, string, blob). The FastSerializable library can skip unknown tags until it finds the endObject tag.
    • Add new object types: Insert entirely new object types into the stream. Ensure these new objects use tagged fields so old readers can skip them.
    • Extend Headers: Add new data to EventBlock or MetadataBlock headers. These headers include a header size field, allowing old readers to skip the additional bytes they do not recognize.
  12. Build PerfView using Visual Studio

    main
    1. Open PerfView.sln in Visual Studio 2026.
    2. To build the solution, select Build -> Build Solution.
    3. To debug, ensure the 'PerfView' project is set as the 'Startup Project' (right-click the project in Solution Explorer and select 'Set as Startup Project'), then press F5.
    4. To build a Release version for deployment:
      • Set the build configuration to 'Release' in the top toolbar.
      • Select Build -> Build Solution (Ctrl-Shift-B).
      • The resulting executable is located at src/PerfView/bin/net462/Release/PerfView.exe (or similar path depending on build type). Only this .exe is required for deployment.
    Build -> Build Solution