BlogsDatadog.NET Memory Profiling

.NET Memory Profiling

.NET Memory Profiling

4
posts
2024

Datadog's .NET profiler has been enhanced to include memory usage profiling, allowing users to identify high CPU consumption due to excessive garbage collection, pinpoint code responsible for memory allocations, and detect potential memory leaks by tracking surviving objects. The system monitors garbage collector activity by analyzing CLR events and CPU consumption of GC threads. For allocations, it leverages the `AllocationTick` event to sample allocations and capture call stacks. This post details the profiling of exceptions and lock contention, including sampling strategies and CLR event handling.

2024

.NET Continuous Profiler: Memory usage | Datadog

5/20/2024

This post details the implementation of memory usage profiling for Datadog's .NET profiler. It covers monitoring garbage collector CPU impact by analyzing CLR events and GC thread CPU consumption, tracking memory allocations using the `AllocationTick` event and current thread stack walking, and identifying surviving objects and memory leaks by employing `Weak` handles and monitoring object age. It also discusses the challenges of upscaling sampled memory data and a pitfall related to object address handling when creating `Weak` handles.

.NET Continuous Profiler: Exception and lock contention | Datadog

4/4/2024

This post details the implementation of exception and lock contention profiling within Datadog's .NET continuous profiler. For exceptions, it describes how to capture exception type, thread ID, and message by leveraging `ICorProfilerCallback::ExceptionThrown` and accessing internal exception fields like `_message`. For lock contention, it explains how to use CLR events (`ContentionStart`, `ContentionStop`) and the `EventPipeEventDelivered` callback to track lock contention duration and identify the holding thread, with specific considerations for different .NET runtime versions.

.NET Continuous Profiler: CPU and wall time profiling | Datadog

2/13/2024

This post details the implementation of CPU and wall time profiling within the Datadog .NET continuous profiler. It explains how application threads are monitored and sampled for CPU and wall time, including the use of `ICorProfilerCallback` methods for thread lifecycle management and the `StackSamplerLoop` class for sampling. It also covers the identification and monitoring of special native threads like those from the garbage collector. For CPU profiling, it describes the sampling frequency, the `IsRunning` function for checking thread status and CPU consumption on Windows and Linux, and the calculation of CPU time consumed. An internal example of using the CPU profiler to reduce CPU consumption is mentioned, along with performance optimizations for the `OsSpecificApi::GetCpuInfo` function.

.NET Continuous Profiler: Under the hood | Datadog

1/9/2024

This post details the technical architecture and implementation choices behind Datadog's .NET profiler, which is designed for continuous operation in production. It covers the profiler's components (samplers, providers, aggregator, exporter), how samples are collected and aggregated into the .pprof format using Rust, and how profiles are associated with traces and spans on the backend using runtime IDs. It also explains the process of cleaning up .NET call stacks for better readability and discusses the decision to implement the profiler in native code (C++ and Rust) running in the same process as the profiled application, rather than using Microsoft's TraceEvent nuget.