[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-105297":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":14,"openIssues":13,"contributorsCount":13,"subscribersCount":13,"size":13,"stars1d":15,"stars7d":15,"stars30d":15,"stars90d":13,"forks30d":13,"starsTrendScore":16,"compositeScore":17,"rankGlobal":10,"rankLanguage":10,"license":18,"archived":19,"fork":19,"defaultBranch":20,"hasWiki":19,"hasPages":19,"topics":21,"createdAt":10,"pushedAt":10,"updatedAt":22,"readmeContent":23,"aiSummary":10,"trendingCount":13,"starSnapshotCount":13,"syncStatus":24,"lastSyncTime":25,"discoverSource":26},105297,"dotheap","neon-sunset\u002Fdotheap","neon-sunset","Mixed-mode live heap snapshot capture and analysis tool for .NET 10 applications with support of standard (WKS\u002FSVR) and Satori GC families","",null,"Rust",55,0,51,1,3,38.6,"GNU Affero General Public License v3.0",false,"main",[],"2026-11-01 00:13:48","# Dotheap\n\n\u003Cimg src=\"assets\u002Ficon.png\" width=\"96\" align=\"right\" alt=\"\">\n\n#### Disclaimer 1\nDotheap is authored entirely with AI tools. Yelling at digital spirits is all you need.\n\n#### Disclaimer 2\nThis tool can and will sometimes produce inaccurate numbers.  \nA lot of its heuristics are tied to specific implementation details of .NET's standard library, GC internals and Roslyn's async state machine layout. Some features are speculative estimations. Providing a _useful_ diagnostic is more important than being absolutely accurate.\n\n## Description\n\nSo what is Dotheap?\nDotheap is a mixed-mode (managed + native) heap snapshot analysis tool for .NET 10 applications which supports both standard (WKS\u002FSVR) and [Satori](https:\u002F\u002Fgithub.com\u002FVSadov\u002FSatori) GC families.\n\n![Memory ownership, async calls and ArrayPool findings in the demo application](docs\u002Fscreenshots\u002Foverview.png)\n\nEver had to respond to an incident or troubleshoot abnormal memory usage or application state at a point in time only to waste hours, thinking \"it's just some 6.7 GiB of RAM, why is it so hard to tell what's using it?\". Dotheap is made to put this to a definitive end.\n\nDotheap does:\n- Complete accounting of _both_ managed and native memory usage in a unified memory graph\n- Diagnosing managed\u003C->native memory leaks\n- Reconstructing async call chains, dependencies, task leaks and async deadlocks\n- Working with larger-than-memory heaps (and larger than free disk space too)\n- Speculative fragmentation source analysis\n- Glibc malloc pointer ownership analysis\n- Dead object graph analysis\n- Detecting shared array pool use-after-return and double-return\n- Automatic runtime symbol downloading and management (ever fought with .NET SoS?)\n- And more\n\nDotheap comes in two forms: CLI and Viewer application both using the shared `heap-core`.\n\nThe CLI runs on Linux, macOS and Windows. It is designed to be agent-friendly but even a human operator may find it useful, should the need arise.\n\nThe Viewer is a native macOS application which mainly exists for recreational purposes of a human operator. In the age of increasing automation, it is designed to evoke a nostalgic feeling of digging through navigation menus, heap information records and \"aha, so that's what the problem is\" without leaving unnecessary guesswork afterwards.\n\n## (Almost) pauseless live heap snapshots \n\n_On Linux systems_, Dotheap supports _live_ heap snapshots.  \nIt implements VM live migration style memory capture mechanism which replaces standard \"request .NET application over IPC to suspend itself and (slowly) write the raw dump to disk\" incompatible with production applications serving live traffic or just actively running.  \n\nThis means you can use `dotheap dump` on live applications with huge heaps with almost no interruption (typical suspension duration is within 250-25ms depending on heap size and modified memory pages).\n\nIn such scenarios, `dotheap dump` writes `dmp.zst` and `smaps.zst` files. The dump is written as 256KiB blocks compressed into ZSTD frames. CLI and Viewer then work directly on this format, indexing and caching produced analysis without ever fully decompressing potentially dozens of gigabytes of data.\n\n_On Apple silicon macOS_, Dotheap uses kernel copy-on-write snapshots: the application keeps running while the dump is written, without requiring .NET IPC. It produces the same compressed dump format, with residency data included in the dump.\n\n## Install\n\n- **macOS 15+:** `brew install --cask neon-sunset\u002Ftap\u002Fdotheap` builds the CLI and Viewer from\n  source, installs `dotheap` on your PATH, and puts `Dotheap.app` in `\u002FApplications`.\n  Requires Xcode 16 or later; Homebrew installs Rust. Use `brew upgrade --cask dotheap` to update both.\n- **Linux:** download a static x86_64 or aarch64 binary from the\n  [releases page](https:\u002F\u002Fgithub.com\u002Fneon-sunset\u002Fdotheap\u002Freleases). No runtime dependencies are required.\n- **Windows:** download `dotheap-windows-x64.zip` from the releases page and extract `dotheap.exe`.\n  No additional runtime or DLLs are required.\n\n## CLI Walkthrough\n\n```sh\ndotheap summary core.dmp                # Memory totals, findings and next commands\ndotheap types core.dmp                  # Types by retained, live or dead bytes\ndotheap object core.dmp 0x7fa16480      # Fields, referrers and a path to a root\ndotheap retained core.dmp 0x7fa16480    # Managed and native memory retained by an object\ndotheap help                            # Commands and common options\ndotheap help dump                       # Capture options, permissions and pauses\n```\n\nStart with `summary` and follow its `next` list. Each suggested command includes the address to\ninspect. An address can point anywhere inside an object or malloc chunk. If it points elsewhere,\nthe error identifies the memory and suggests a suitable command.\n\nAn excerpt from the demo's `summary --limit 3` output:\n\n```text\nlargest retainers: (376 more; raise --limit)\n  retained   managed  native  count  example     name\n  171.6 MB  171.6 MB     0 B      1  0x7fa16480  System.Collections.Concurrent.ConcurrentDictionary`2\u003CSystem.String, Shop.CacheEntry>\n   42.2 MB   38.2 MB  4.0 MB      1  0x7fc09018  static fields (System.Object[])\n   10.4 MB   10.4 MB     0 B      1  0x7fa143a8  System.Collections.Concurrent.ConcurrentQueue`1\u003CShop.LogRow>\n```\n\nTo inspect the large cache and list its entries:\n\n```sh\ndotheap instances core.dmp CacheEntry --live --sort retained\ndotheap retained core.dmp 0x7fa16480 --limit 0\ndotheap object core.dmp 0x7fa16480 --json\n```\n\n`instances` accepts an exact type name or a name fragment. Quote names that contain spaces or\nshell characters. Use `--match` to filter type names and `--text` to filter instances by their\ncontents or identifying string fields; `dotheap help \u003Ccommand>` lists the options each accepts.\n\n## Managed and native ownership\n\nA managed cache can hold native buffers through `SafeHandle` or `IntPtr` fields. Native code can\nkeep managed objects alive through GC handles. Dotheap follows both directions in one graph, so\nroot paths and retained sizes can include managed objects and native allocations.\n\nRetained size is the memory reachable only through a particular object or allocation in that\ngraph. It does not predict an immediate drop in RSS. A pointer establishes a reference, not proof\nof ownership: conservative scans can include stale pointers or miss encoded ones. Native allocation\nanalysis requires Linux\u002Fglibc; see the [analysis reference](docs\u002Fanalysis.md#managed-and-native-ownership)\nfor reference rules, native-root categories and chunk naming.\n\n## Capture a process\n\n```sh\ndotheap ps\ndotheap dump 4321 --out core.dmp.zst\ndotheap summary --pid 4321\n```\n\nProcess discovery and capture are supported on Linux and macOS. `ps` lists running processes\nand identifies .NET applications by diagnostics sockets in `TMPDIR` and `\u002Ftmp`. `--pid`\ncaptures first, then runs the selected analysis command. `--out`, `--pause` and `--offline` also apply.\nLinux and Apple silicon macOS default to live capture; .NET diagnostics are only needed for `--offline`.\n\n### Live Linux capture\n\nBy default, Linux capture copies memory while the process runs, then stops its threads to read\nregisters and finish the copy. There can be several brief stops before the final one. Busy\nprocesses, large heaps, low memory and slow storage can still produce long pauses. Other processes\ncan continue changing shared memory while the target is stopped.\n\nCapture needs ptrace access: usually root, or the target user with suitable process permissions\nand `kernel.yama.ptrace_scope`. If live capture is unavailable or fails, Dotheap stops. It never\nswitches to runtime capture automatically; that requires `--offline` and has the longer pause below.\n\nCapture fails if the process exits or replaces its address space before the final copy, or a\nrequired memory or register read fails at the final stop. Deleting a mapped file does not by itself\nmake its memory unreadable. Deleted mappings are identified by `files` and in the Viewer.\n\n### Live macOS capture\n\nOn Apple silicon, Dotheap takes a kernel copy-on-write snapshot. The process keeps running while\nthe snapshot is read and compressed. Capture needs macOS debugger access; protected applications\ncan deny access even as root. Translated x86 processes are not supported. Device I\u002FO mappings\nare omitted because reading them can affect the device.\n\nIf the kernel cannot create a snapshot, `--pause` suspends the process until the dump is written.\nThe Viewer asks before using this fallback. Cancellation, failure or termination of Dotheap\nreleases the suspension. Other processes can still change shared memory during capture.\n\n### Runtime capture\n\nWith `--offline` (or **Pause for .NET runtime dump** in the Viewer), Dotheap asks the .NET runtime\nto write a full dump. **The process stays paused for the entire raw-dump write.** For large heaps,\nthis makes runtime capture impractical\non services that must keep serving traffic.\n\n```sh\ndotheap dump 4321 --offline --out core.dmp.zst\n```\n\nDiagnostics must be enabled and the socket accessible.\nRun as the target user or root. The runtime writes as the target user, who must have permission\nto write to the output directory. Compression starts after the process resumes. A filename without\n`.zst` keeps the raw dump. If compression or publication fails, the error gives the raw dump's\nrecovery path.\n\n### Output and resource use\n\n`--out` (`-o`) accepts a filename or an existing directory, relative to Dotheap's working directory.\nA directory gets `\u003Cprogram>-\u003Cpid>-\u003Ctime>.dmp.zst`. The default is the cache's `live` directory.\nWhen root requests a runtime dump of another user's process, the default is a new directory in\n`\u002Ftmp` owned by that user. Existing output files are never replaced.\n\nLive capture always writes Zstandard data. Progress, disk use and pause times go to stderr;\nstdout receives the completed path, or `{\"dump\":\"\u003Cpath>\"}` with `--json`. Linux capture also saves\nsmaps beside the dump for [resident-memory analysis](#resident-memory); macOS embeds this data in the dump.\nFull dumps include readable shared-library mappings, so their contents can be much larger than\nthe process's physical footprint.\n\nLive capture needs space for the compressed output and, on Linux, temporary copies. It checks free space\nperiodically and stops below 2 GiB available to non-root users. On Linux, pages copied at the final stop\ncan spill to disk when memory is limited, which lengthens the pause. Runtime capture needs space\nfor both the full raw dump and its compressed output until compression finishes.\n\nOn Linux, Dotheap makes itself a preferred OOM victim, but cannot guarantee the target survives memory\npressure. Temporary files can remain after a forced termination on filesystems without unnamed\nfile support. See [Live capture implementation](docs\u002Fcapture.md) for the copying procedure,\nresource limits and cleanup behaviour.\n\n## Compatibility\n\n| Dump format | Architectures | Managed heaps |\n|---|---|---|\n| Linux ELF core | x64, arm64 | Satori; stock CoreCLR workstation and server GC with regions |\n| macOS Mach-O core | arm64 | Satori; stock CoreCLR workstation and server GC with segments |\n\nUse a full dump from `dotheap dump`, `dotnet-dump collect --type Full`, a kernel core or `gcore`.\nThe analysis host can differ from the dump's platform: for example, read a Linux dump on macOS.\nThe Windows CLI also reads these formats; Windows minidumps are not supported.\n\n.NET and ASP.NET Core **10.0.0–10.0.14** are supported, including intermediate patch releases.\nVersions outside this range open with warnings in the CLI and Viewer. The summary identifies the\nruntime, .NET libraries and ASP.NET Core versions. [versions.rs](crates\u002Fheap-core\u002Fsrc\u002Fversions.rs)\ndefines the range; [Development](docs\u002Fdevelopment.md#net-version-compatibility) records the source\nchecks and dump tests behind it.\n\nSatori heap layouts are selected by structural checks against region headers, rather than a\nruntime-version allowlist. An ambiguous or unsupported layout stops analysis. The summary reports\nwhich layout matched; the [Satori reference](docs\u002Fanalysis.md#satori-layouts-and-region-contents)\nlists supported layouts and explains region contents. .NET library and ASP.NET Core version\nwarnings still apply to Satori dumps.\n\nNative-only Linux processes get mapping, thread and glibc malloc analysis. This includes C, C++\nand Rust programs using glibc's allocator. Go's managed heap is outside malloc, so its dumps\nprimarily provide mappings and stacks. Musl and other allocators have no chunk analysis; macOS\nmalloc zones are not walked. Glibc analysis has been verified on 2.36 and 2.39.\nNative-only macOS processes get mapping and thread analysis.\n\n### Symbols and metadata\n\nFull runtime dumps normally include assembly images; kernel cores and `gcore` can omit them.\nSupply missing app or runtime assemblies with repeatable `--dlls` options:\n\n```sh\ndotheap summary core.dmp --dlls .\u002Fapp --dlls .\u002Fruntime\ndotheap symbols core.dmp\n```\n\nDirectories are searched recursively. Missing metadata is listed in the summary; object sizes\nand managed liveness do not depend on type names. Matching portable PDBs, embedded or in a\n`--dlls` directory, supply await and callback source locations.\n\n`symbols` downloads .NET runtime debug files for Linux dumps from Microsoft's symbol server and\ncaches them by build ID. The Viewer downloads them automatically unless **File > Download Runtime\nSymbols When a Dump Opens** is disabled. Cached symbols are reused. Findings run without waiting\nfor downloads; analysis refreshes when new symbols arrive. Large debug files can take several minutes\nto download in the background.\n\nSatori and other custom runtimes need debug files from their own builds, such as `libcoreclr.so.dbg`,\nin a `--dlls` directory. Native binaries are also sought at their recorded paths. Dotheap accepts\na binary only if its build ID matches, or its first page matches when no build ID is available.\n\n## Commands\n\n| Command | What it shows |\n|---|---|\n| `summary` | Memory by kind, managed and malloc totals, findings, warnings, large retainers and commands to run next. |\n| `types`, `instances \u003Ctype>` | Types by retained\u002Flive\u002Fdead bytes or count; instances by retained size or object size, with identifying strings and reachability filters. |\n| `object \u003Caddress>`, `retained [\u003Caddress>]` | Fields, contents, referrers and a root path; managed and native dominator children grouped by type. Without an address, `retained` lists root sources. |\n| `search \u003Ctext>` | Matching findings, report rows, methods, callbacks, fields, types and native groups; an address identifies the memory there. |\n| `native`, `chunk \u003Caddress>` | glibc malloc memory by type or referrer and library; size distributions with `--group`, individual allocations, arena heaps, and reference evidence. |\n| `malloc-arenas` | Free and top-chunk memory by attached thread count; glibc parameters; estimated effects of `malloc_trim(0)`, trim\u002Farena tunables and restart. |\n| `regions [\u003Caddress>]`, `handles` | Regions grouped by generation, queue or size; one region and its types; GC handles by kind and target type. |\n| `memory`, `bytes \u003Caddress>`, `find \u003Cvalue>` | Memory by kind; a hex dump with resolved 8-byte pointers; every detected occurrence of an 8-byte value in fields, chunks, stacks or other memory. |\n| `garbage`, `fragmentation` | Dead objects and the structures they retain; dead objects and unused committed space, attributed to GC rules and surviving objects. GC storage, objects pending finalization and unparsed bytes are excluded from fragmentation attribution. |\n| `tasks [\u003Caddress>]`, `async` | Running, queued and waiting calls by async stack. An address selects calls sharing an awaited object, their call tree, state-machine fields and root paths. |\n| `threads [\u003Ctid>]`, `stacks` | Thread functions and estimated frames; a merged tree of managed frames with each group's running or waiting state. |\n| `network`, `connections` | Sockets, endpoints, descriptors, owners and pending I\u002FO; Kestrel\u002FHttpClient requests; pools and socket engines. `connections` focuses on active requests and queued work. |\n| `files` | Managed handles with path, access, position, buffered bytes, pending I\u002FO and owner; native C++ paths and estimated descriptors; mapped and deleted files. |\n| `timers` | Timer sources, callback methods or awaiting calls, owners, periods and relative ages. |\n| `collections`, `strings`, `zero-arrays`, `boxed`, `finalizable` | Collection capacity, duplicate strings, mostly zero arrays, boxed values and finalizer states. |\n| `findings` | Heap integrity, potential leaks, blocked work and inefficient memory use, with commands for detailed reports. |\n| `verify` | Invalid object, type and runtime structures, with field addresses and values. Works without the reference graph. |\n| `ps`, `dump \u003Cpid>` | Discover local processes or capture one. Linux and Apple silicon macOS default to live capture. Runtime capture requires `--offline`. |\n| `cache`, `symbols` | List or remove analysis caches; download matching .NET runtime symbols. |\n| `report` | A full text report, also available as `dotheap core.dmp`. Uses `--top` rather than `--limit`; see `dotheap help report`. |\n\nUse `dotheap help \u003Ccommand>` for arguments, options and interpretation. Every analysis command takes\n`\u003Ccore>` before its command-specific arguments, or `--pid \u003Cpid>` to capture first.\n\n## Findings\n\n`findings` lists potential problems; `summary` includes a ranked overview.\nRun a command below to inspect the evidence. The Viewer links findings to the relevant objects\nand detailed views. See the [analysis reference](docs\u002Fanalysis.md) for interpretation and limits.\n\n| Command | What to investigate |\n|---|---|\n| `verify` | Corrupt MethodTables, object sizes, GC descriptors, references and runtime links. Missing memory is reported separately. See [heap integrity](docs\u002Fanalysis.md#heap-integrity) for scope and limits. |\n| `async`, `blocked`, `locks` | Shared waits, abandoned calls, dependency cycles, blocked threads and possible starvation or deadlocks. Frames and waiters are inferred; a snapshot cannot measure wait duration. |\n| `arraypool` | Double returns, references to returned arrays, and possible missed returns. Directly allocated arrays can resemble missed returns. |\n| `large-objects` | Large allocations by type, dead objects awaiting collection and unused space in their regions. |\n| `cancellation`, `events` | Callback registrations or subscriptions that retain objects longer than intended. |\n| `timers` | Timer callbacks or awaiting calls, owners and periods. Ages are relative to other timers in the dump, not capture time. |\n| `instance-counts` | High counts of commonly shared or disposable types, grouped by owner. |\n| `exceptions` | Repeated throw sites, retained exceptions and unobserved faulted tasks. |\n| `connections`, `network`, `files` | Requests, queues, sockets, file handles, pending I\u002FO and mapped or deleted files. Native file descriptors are estimates. |\n| `finalizer-backlog`, `native-held-by-dead` | Native memory waiting for finalizers or referenced only by dead managed objects. Stale pointers can resemble leaks. |\n| `finalizable` | Registered, suppressed, resurrected, pending and dead objects of finalizable types. |\n\nFindings identify evidence to inspect. A high count or an unreferenced allocation alone does not\nprove a leak. Async analysis targets the .NET 10 state-machine model, not .NET 11 runtime async.\n\n## macOS viewer\n\nOpen `.dmp` or `.zst` files from Finder or **File > Open Dump…**. Each dump has its own window,\nnavigation and selections. Opening the same dump again brings its window forward. Opening an\nsmaps file selects the dump beside it.\nUse **File > Dump Running Process…** to capture a running application and open the dump.\nThe list groups .NET and other applications separately.\n\nSelect a managed object or native allocation to inspect it in the sidebar. Dominators and Roots\ninclude both kinds, with links to their references and root paths. Native Memory separates allocation\ngroups, malloc heaps, mappings and overview statistics so each table has its own scrolling area.\nSearch (⇧⌘F) finds types, methods,\ncallbacks, findings, native classes, pages and addresses. Back and Forward (⌘[ and ⌘], or the\nmouse buttons) restore earlier pages and selections.\n\nTo launch a specific view in a separate process:\n\n```sh\nopen -n Dotheap.app --args -dump core.dmp\nopen -n Dotheap.app --args -dump core.dmp -section \"Managed Heap\" -heapView \"Region Map\" -region 0x44200000\nopen -n Dotheap.app --args -dump core.dmp -section Threads -threadsView Locks\n```\n\nOther startup options include `-smaps \u003Cfile>`, `-type \u003Cname>`, `-object \u003Caddress>`, `-task \u003Caddress>`,\n`-finding \u003Ccheck>`, `-search \u003Ctext>`, `-networkView Requests` and `-filesView \"Mapped files\"`.\n\n## Resident memory\n\nMemory contents alone do not record RSS or physical page sizes. Live capture also records\nresidency, in a smaps file on Linux and inside the dump on macOS. For other dumps, supply\n`\u002Fproc\u002F\u003Cpid>\u002Fsmaps` on Linux or `vmmap -wide \u003Cpid>` output on macOS, taken close to the dump:\n\n```sh\ndotheap summary core.dmp --smaps core.smaps\n```\n\n`.gz` and `.zst` are accepted. Without `--smaps`, Dotheap tries `\u003Cname>.smaps.zst`, `.smaps.gz`, then\n`.smaps` beside `\u003Cname>.dmp.zst` or `\u003Cname>.dmp`. Linux capture saves smaps after the target resumes.\nAn external file overrides embedded residency.\n\nFor Linux dumps with matching residency data, process totals and memory grouped by kind, stack, malloc heap and\nmapped file use RSS. On mismatch, a warning explains why, those views use dump estimates, and the\nResidency view still shows the supplied data. Zero-filled heap pages make estimates uncertain:\nthey can be resident after writes or because a huge page backs them.\n\nFor macOS dumps, the Residency view shows resident, private and compressed or swapped pages by\nregion category. Physical footprint is shown separately: shared pages can occur in several\nmappings, so their sum is not the process's physical footprint. Capture records region residency\nbefore copying memory and physical footprint just before the snapshot.\n\nMatching checks reject obvious differences; they cannot prove the files describe the same instant.\nResidency can change between captures. The [analysis reference](docs\u002Fanalysis.md#residency-and-storage)\nexplains the checks and estimates.\n\n## Scripts and agents\n\n- Use `--json` for structured output. Byte counts are numbers of bytes; addresses are `\"0x...\"`\n  strings. JSON text has no table-cell limit, although preview fields can still be abbreviated.\n  Text tables can shorten cells over 80 characters except in the last column. Human-readable\n  sizes use powers of 1024.\n- `--limit` defaults to 20 rows per list; 0 returns all rows. A shortened JSON list has a sibling\n  `\u003Cname>Omitted` count. Check it before treating a list as complete.\n- Results go to stdout; processing notices, capture progress and warnings go to stderr.\n  `--progress` adds processing phases and durations. Exit status 0 means success, 1 means failure,\n  and 2 means invalid arguments. Discard stdout from a failed command.\n- Start with `summary` and follow its `next` commands, as in the [walkthrough](#cli-walkthrough).\n  Use named commands for subsequent queries; `report` is text-only.\n- Rows use deterministic ordering and tie-breakers. Keep the dump available even after analysis;\n  some details are read from it on demand.\n\n```sh\ndotheap summary core.dmp --json > summary.json\ndotheap instances core.dmp CacheEntry --live --limit 0 --json > entries.json\ndotheap dump 4321 --out core.dmp.zst --json > capture.json\n```\n\n## Cache\n\nThe first command processes the dump; later commands reuse its analysis cache. Findings and detailed\nreports are saved when first requested. The cache identifies the dump by its path and file identity;\nreplacing the dump invalidates its cached analysis.\n\n| Platform | Default cache root |\n|---|---|\n| macOS | `~\u002FLibrary\u002FCaches\u002Fdotheap` |\n| Linux | `$XDG_CACHE_HOME\u002Fdotheap`, or `~\u002F.cache\u002Fdotheap` |\n| Windows | `%LOCALAPPDATA%\\dotheap`, or `%TEMP%\\dotheap` if `LOCALAPPDATA` is unset |\n\n`dotheap cache` prints the actual root. Object and reference data use files the OS can page out,\nbut working memory still depends on object counts, references and the requested analysis.\n\nDumps written by Dotheap are read directly as compressed blocks. Other `.zst` files may need a\nsecond compressed copy in the cache; allow space comparable to the compressed source. Random\nreads can also expand data into a temporary sparse file. Its disk use grows with the nonzero\npages accessed and can approach the expanded dump size. The file is removed when it is no longer\nin use. See [Residency and storage](docs\u002Fanalysis.md#residency-and-storage) for the storage paths.\nZstandard support is built in; analysis needs no installed `zstd` command.\n\nThe Viewer offers to convert dumps that require sequential decompression. Conversion writes\nindependent 256 KiB frames at compression level 3, using all available CPU cores.\n**Replace Original** verifies a temporary converted file before atomically replacing the source,\nthen removes its obsolete compressed cache. **Keep Original…** saves a separate copy and copies\nan adjacent memory map. Both options reuse valid object and reference cache files and need\ntemporary space for the compressed output. Cancellation or failure before replacement preserves\nthe original. Conversion streams directly to compressed output; it does not write a full raw dump.\n**Open Original** uses the existing cache path. The suggestion can be disabled in Settings.\n\n```sh\ndotheap cache                         # Cached analyses, source paths and disk use\ndotheap cache --delete missing        # Caches whose recorded source dump is missing\ndotheap cache --delete '\u003Cfolder>'     # One folder listed by dotheap cache\ndotheap cache --delete all            # All analysis caches; preserves dumps and symbols\ndotheap summary core.dmp --rebuild    # Process again in the default cache\n```\n\n`--cache \u003Cdirectory>` chooses a cache directory. `--no-cache` processes an uncompressed dump without\nsaving results; compressed dumps require a cache. The Viewer has **File > Cache**, **File > Process\nDump Again** and **File > Open Recent**. Deleting a cache makes the next open process the dump\nagain. Dumps and caches contain application data and can include credentials; keep them private.\n\n## Build\n\nThe CLI and analysis core use Rust 1.94 or later. Build with a C compiler available for the bundled\ncompression and TLS dependencies. On Windows, use the MSVC Rust toolchain and Visual Studio C++\nBuild Tools.\n\n```sh\ncargo build --release --locked -p dotheap\ntarget\u002Frelease\u002Fdotheap help\n```\n\nThe Viewer needs macOS 15+, Xcode 16 or later with Swift 6, and Python 3. The build script\nlinks the Rust core statically into the app:\n\n```sh\nscripts\u002Fbuild-macos.sh\nopen Dotheap.app\n```\n\nFor a static Linux binary, install `musl-tools` and build on the target architecture:\n\n```sh\nrustup target add x86_64-unknown-linux-musl\nCC=musl-gcc cargo build --release --locked -p dotheap --target x86_64-unknown-linux-musl\nstrip target\u002Fx86_64-unknown-linux-musl\u002Frelease\u002Fdotheap\n# On arm64, use aarch64-unknown-linux-musl in both paths.\n```\n\nThese binaries also run on glibc distributions; the destination needs no musl installation.\nUse a binary built for the destination's CPU architecture.\n\nFor a Windows binary with the C runtime linked statically, use an explicit target:\n\n```powershell\ncargo build --release --locked -p dotheap --target x86_64-pc-windows-msvc\ntarget\u002Fx86_64-pc-windows-msvc\u002Frelease\u002Fdotheap.exe help\n```\n\nSee [Development](docs\u002Fdevelopment.md) for tests, real-dump comparisons, packaging and third-party\nnotices. [Swift and Rust interop](docs\u002Finterop.md) describes the Viewer's data access and ownership.\n\n## License\n\nCopyright (C) 2026 Arseniy Zlobintsev.\n\nDotheap is licensed under the [GNU Affero General Public License, version 3](LICENSE)\n(`AGPL-3.0-only`). Third-party components retain their own licenses; see\n[third-party notices](THIRD-PARTY-NOTICES.txt).\n\nThe Viewer provides both license documents in **Dotheap > About Dotheap**.\n",2,"2026-10-31 04:26:22","CREATED_QUERY"]