Repository navigation
Releases: stephenberry/heapscope
Release list
heapscope 0.3.0
[dependencies]
heapscope = "0.3"Changed
- Text summaries name functions, not return addresses. Every summary, including the one a failing assertion prints, renders each frame as its function name, the way folded output does since 0.2.0, instead of repeating an address and an absolute image path. The profile files keep every address, and
write_text_summary_withtakesSymbolizedfor the old rendering. (#15) - The ranking leaves out sites that allocated nothing. After
Profiler::reset, a program point that only held memory from before the reset is no longer listed among the top sites; the summary says how many were left out. (#15) - Failure profiles go under
target/. WithHEAPSCOPE_ASSERT_PROFILEunset, a failing assertion writes its profile totarget/heapscope/(target/<triple>/heapscope/with--target, followingCARGO_TARGET_DIR) rather than into the package's source tree. (#17)
Added
HeapStats::allocations_since(&mark)returns the countassert_alloc_count!(since: mark)checks, or aMarkErrorsaying why the mark cannot be compared. (#15)RegionBreakdown::totalscarries the run's counters from the same instant as the rows, so the rows plusoutside_regionsadd up to it exactly. (#15)CHANGELOG.md. (#15)
Fixed
heapscope 0.2.0
[dependencies]
heapscope = "0.2"Changed
- Folded output names functions, not return addresses. Each frame is its demangled function name, so a flame graph merges a function however many call sites reached it. The 0.1.0 addressed rendering is still available through
write_folded_with, andheapscope-symbolize -f foldedwrites the new form too. (#7) - Frames are named at the call site.
heapscope-symbolizeand in-process lookup now resolve the call instruction rather than the return address, so a frame no longer takes the name of whatever the compiler placed after the call, which across inlining is often another function. Recorded addresses are unchanged.
Added
Profiler::resetrestarts a running profile's counts while keeping what is live, to leave a warm-up out. Every output except folded stacks records that a reset happened. (#9)RegionBreakdown::get()reads per-region totals without taking a full snapshot, and a new(no region)row covers what no region did, so the rows sum to the run's totals. (#8)assert_alloc_count!gains a ceiling form (<= n) and asince: markform. (#5)
Fixed
- The live-block table no longer stops recording new blocks after long churn of distinct addresses at its size limit. (#11)
heapscope 0.1.0
First release. A heap profiler that tracks every allocation, attributes it to the call site that made it, and writes a profile you can open in a bundled single-file viewer or in Valgrind's DHAT viewer.
[dependencies]
heapscope = "0.1"What it does
- No dependencies outside the standard library.
[dependencies]is empty and enforced by a test, so what reaches your build is this crate andstd. - About 97 ns per allocation, against
dhat-rs's 8,300 on the same workload — a factor of roughly 85. Sampling trades exactness for most of the remaining cost, and the profile says which one it is. - Four outputs from one reading, so a summary and a file can never disagree about the same run: DHAT v2, a native JSON superset, a self-contained HTML page, and folded stacks for any flame graph tool.
- Numbers a test can read, so "this parser allocates at most 64 KiB" runs on every commit instead of being measured once and written in a comment.
- Thread and phase attribution, which DHAT v2 has no field for.
- Offline symbolization via the bundled
heapscope-symbolize, which matters most on Linux, where the loader names almost nothing at record time.
Platforms
macOS aarch64, Linux x86_64, Linux aarch64, and Windows x86_64. All four run the test suite in CI on every push, Windows natively. AddressSanitizer and ThreadSanitizer run it as well, each behind a positive control that fails the job if the sanitizer cannot see a planted defect through this crate's #[global_allocator], and Miri runs it under the race detector.
musl / Alpine is not supported and never will be.
Requirements
heapscope::Alloc must be the program's #[global_allocator], and x86_64 targets need -C force-frame-pointers=yes. A run missing either refuses to start and says which, rather than producing an empty or much slower profile. MSRV is 1.96.
Status
Pre-1.0, and the version number is the promise: the public API may still change. What is still unproven is written down rather than left out — the cost of RtlCaptureStackBackTrace on Windows is unmeasured, no Windows browser has opened the bundled page, and Module::bias on Windows is a relative virtual address rather than the address the file records, so llvm-symbolizer needs --relative-address there and addr2line cannot be used at all.