Apply Poisson sampling correction to collapsed jemalloc heap profiles#102759
Apply Poisson sampling correction to collapsed jemalloc heap profiles#102759antonio2368 merged 5 commits intomasterfrom
Conversation
Previously, `JemallocProfileSource::generateCollapsed` reported raw sampled bytes/counts without the Poisson sampling correction that jeprof applies via `AdjustSamples`. This caused collapsed profiles to underestimate actual allocation sizes (e.g. ~5.9 GB raw vs ~11.2 GB corrected for a real profile with 524288-byte sampling interval). The fix parses the `heap_v2/N` header to extract the sampling interval, then scales each sample by `1/(1-exp(-mean_size/interval))` using `std::expm1` for numerical stability. Edge cases (zero bytes, zero count, non-finite results, overflow) are guarded. Also adds a `WriteBuffer` overload of `symbolizeJemallocHeapProfile` and unit tests verifying the correction against a hardcoded expected value computed from jeprof's formula. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
Workflow [PR], commit [a795f5e] Summary: ❌
AI ReviewSummaryThis PR applies Poisson sampling correction to collapsed jemalloc heap profiles so totals match Missing context
Findings❌ Blockers
Tests
ClickHouse Rules
Final Verdict
|
Use tryReadIntText instead of parseInt so that malformed heap_v2 headers (e.g. heap_v2/abc) return 0 instead of throwing, keeping collapsed output generation best-effort. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Verify that heap_v2/abc falls back to raw values without throwing. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
# Conflicts: # src/Processors/Sources/JemallocProfileSource.cpp
Resolve conflict in symbolizeJemallocHeapProfile overloads — master already extracted pullProfileLines and added symbolizeJemallocHeapProfileToString, so drop the redundant WriteBuffer overload and use the new API in tests. Also use std::move on out.str() to avoid copying the string buffer. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
| std::filesystem::remove(input); | ||
| } | ||
|
|
||
| /// When the heap_v2 header has a malformed interval (e.g. "heap_v2/abc"), |
There was a problem hiding this comment.
CollapsedMalformedHeaderRawPassthrough verifies malformed heap_v2 headers, but it does not cover malformed allocation records (e.g. invalid <live_bytes> in count mode or invalid <live_count> in bytes mode).
That gap matters here because collapsed parsing now unconditionally parses both fields before choosing the output metric, so malformed data in an otherwise-unused field can raise an exception where previous behavior was best-effort. Please add a regression test for malformed metric fields to lock this behavior down.
LLVM Coverage Report
Changed lines: 96.00% (120/125) · Uncovered code |
| WriteBufferFromOwnString out; | ||
| pullProfileLines(input_filename, format, symbolize_with_inline, out); | ||
| return out.str(); | ||
| return std::move(out.str()); |
There was a problem hiding this comment.
Shouldn't it always return rvalue?
There was a problem hiding this comment.
It probably makes sense to always return rvalue, not sure if it will break somewhere but we can check.
There was a problem hiding this comment.
Of course, but out.str() should be an rvalue already, to be precise out.str() is an prvalue and std::move(out.str()) is an xvalue.
And RVO should be applied here before
I don't understand why clang-tidy does not complain about this line...
There was a problem hiding this comment.
I'm not sure I follow. out.str() returns std::string & so it's lvalue. Am I missing something?
There was a problem hiding this comment.
Oh, sorry for the noise, I thought that str() returns std::string.
Cherry pick #102759 to 26.2: Apply Poisson sampling correction to collapsed jemalloc heap profiles
…sed jemalloc heap profiles
Cherry pick #102759 to 26.3: Apply Poisson sampling correction to collapsed jemalloc heap profiles
…sed jemalloc heap profiles
Backport #102759 to 26.2: Apply Poisson sampling correction to collapsed jemalloc heap profiles
Backport #102759 to 26.3: Apply Poisson sampling correction to collapsed jemalloc heap profiles
Collapsed jemalloc heap profiles generated by
system.jemalloc_profile_textandSYSTEM JEMALLOC FLUSH PROFILEreported raw sampled bytes without the Poisson sampling correction that jeprof applies. This caused the reported totals to underestimate actual allocation sizes — for example, ~5.9 GB raw vs ~11.2 GB corrected for a profile with the default 524288-byte sampling interval.The fix parses the
heap_v2/Nheader to extract the sampling interval, then scales each sample by1/(1-exp(-mean_size/interval))matching jeprof'sAdjustSamplesalgorithm. Usesstd::expm1for numerical stability with small ratios and guards against edge cases (zero bytes, non-finite results, overflow).Also adds a
WriteBufferoverload ofsymbolizeJemallocHeapProfileand unit tests.Changelog category (leave one):
Changelog entry (a user-readable short description of the changes that goes into CHANGELOG.md):
Apply Poisson sampling correction to collapsed jemalloc heap profiles to match jeprof output. Previously the collapsed format underestimated actual allocation sizes by not accounting for the sampling probability.
Documentation entry for user-facing changes
No documentation changes needed — this is a correctness fix for existing functionality.
🤖 Generated with Claude Code