A live allocation flame graph for .NET. Attach it to a running process and watch where the memory goes, in real time, as a flame graph that actually moves: allocation hot paths rise and glow, garbage collections sweep through the scene, and a leak reveals itself as a bright ridge that won't come down while everything around it rises and falls.
Every allocation Cinder shows you was captured live from a real .NET process. Nothing is scripted, faked, or re-timed. That's the whole point, and it's covered properly in the methodology.
- Attach and watch.
cinder attach <pid>opens a GPU-rendered flame graph of a running .NET 8+ process's allocations, out of process, with no changes to the target. Hot paths glow, collections sweep, the graph eases rather than snaps. - Record and replay.
cinder record <pid> -o session.cndrcaptures a session to a portable file;cinder play session.cndrreplays it deterministically, with play, pause, scrub, variable speed, jump-to-collection, and focus-on-the-fastest-growing-path. The same recording renders an identical film every time. - Export.
cinder export session.cndr --aspect 9:16 --format gifturns any recording into a shareable clip or a still, at 16:9, 1:1, or 9:16, with the leak reveal and the collection sweeps marked automatically. - Gallery. Launch with nothing attached and you get a set of curated real recordings to play straight away: a calm, well-behaved app; an allocation-heavy churn; and the flagship leak.
There's a Windows desktop app and a cinder CLI. A static web player replays recordings in the browser for the gallery, so you can watch a session without installing anything.
.NET memory problems are common and the tooling for them is snapshot-oriented and, frankly, a chore. Nobody has made watching allocations pleasurable. The runtime already exposes exactly the right telemetry to do it well and cheaply, sitting there unused for this. Cinder is what happens when you point real-time graphics at that stream instead of a static table.
It's an R&D build under Fortitude Omnis. It doubles as a genuinely useful profiler for our own work and as a showcase: the same hands that write the security tools also write the render loop.
Cinder's default mode samples allocations (roughly one event per 100 KB per type), so figures are honest estimates of relative pressure, not exact byte counts, and they're labelled as sampled wherever they appear. It measures its own overhead on the target and shows it. Collections are correlated and first-class. Symbol resolution degrades gracefully from full file-and-line down to a raw address, and says which. The methodology page spells all of this out, including why full mode costs more and why NativeAOT isn't supported.
Requires the .NET 10 SDK (the solution uses the .slnx format); the projects target net8.0. Windows, with a GPU that can hold a Direct3D 11 swapchain.
dotnet build Cinder.slnx -c Debug
dotnet test Cinder.slnx
Then, for the desktop app and CLI:
# watch a running process live
cinder attach <pid>
# record a session, then replay it
cinder record <pid> -o session.cndr --duration 30
cinder play session.cndr
# make a shareable clip and a still
cinder export session.cndr --aspect 9:16 --format gif -o clip.gif
cinder export session.cndr --aspect 9:16 --format still -o still.png
Launch the app with no arguments to open the gallery.
- Capture attaches over EventPipe and turns the sampled allocation and collection stream into a small, typed event model, with call stacks stitched via TraceLog and symbols resolved along a four-rung ladder.
- Model aggregates that stream into a call tree keyed by call site, decays per-node heat, lays the tree out so bars keep their place as sizes change, and eases a render model toward it on a fixed timestep. That fixed timestep is what makes replay deterministic.
- Render draws the whole scene in a single instanced Direct3D 11 draw call, easing between the previous and current tick on the GPU, with HDR glow on the hot nodes, generation-tinted collection pulses, and the leak's survivor rim.
- Recording is the
.cndrformat: chunked, versioned, CRC-framed, storing raw events so the film is always recomputed and never drifts.
The heavy lifting lives in four independent libraries behind one recording format, which is also what lets the browser player replay the same files.
Pacing, camera, and easing are directed for the showcase. The events never are. No allocation is invented, reordered, re-timed, or embellished, ever. If you suspect the glowing ridge is scripted, go and record your own leak and watch it do the same thing.