[Profiler] Improve memory consumption LibrariesInfoCache#8777
Conversation
|
45ba215 to
ce3a404
Compare
Execution-Time Benchmarks Report ⏱️Execution-time results for samples comparing This PR (8777) and master. ✅ No regressions detected - check the details below Full Metrics ComparisonFakeDbCommand
HttpMessageHandler
Comparison explanationExecution-time benchmarks measure the whole time it takes to execute a program, and are intended to measure the one-off costs. Cases where the execution time results for the PR are worse than latest master results are highlighted in **red**. The following thresholds were used for comparing the execution times:
Note that these results are based on a single point-in-time result for each branch. For full results, see the dashboard. Graphs show the p99 interval based on the mean and StdDev of the test run, as well as the mean value of the run (shown as a diamond below the graph). Duration chartsFakeDbCommand (.NET Framework 4.8)gantt
title Execution time (ms) FakeDbCommand (.NET Framework 4.8)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (8777) - mean (73ms) : 70, 75
master - mean (73ms) : 70, 77
section Bailout
This PR (8777) - mean (78ms) : 74, 81
master - mean (76ms) : 74, 78
section CallTarget+Inlining+NGEN
This PR (8777) - mean (1,096ms) : 1046, 1146
master - mean (1,095ms) : 1041, 1150
FakeDbCommand (.NET Core 3.1)gantt
title Execution time (ms) FakeDbCommand (.NET Core 3.1)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (8777) - mean (113ms) : 108, 118
master - mean (114ms) : 108, 120
section Bailout
This PR (8777) - mean (117ms) : 112, 123
master - mean (113ms) : 111, 116
section CallTarget+Inlining+NGEN
This PR (8777) - mean (789ms) : 764, 815
master - mean (793ms) : 767, 818
FakeDbCommand (.NET 6)gantt
title Execution time (ms) FakeDbCommand (.NET 6)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (8777) - mean (101ms) : 97, 106
master - mean (100ms) : 96, 104
section Bailout
This PR (8777) - mean (104ms) : 98, 109
master - mean (103ms) : 99, 108
section CallTarget+Inlining+NGEN
This PR (8777) - mean (951ms) : 910, 992
master - mean (944ms) : 902, 986
FakeDbCommand (.NET 8)gantt
title Execution time (ms) FakeDbCommand (.NET 8)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (8777) - mean (98ms) : 96, 101
master - mean (99ms) : 95, 102
section Bailout
This PR (8777) - mean (100ms) : 98, 103
master - mean (99ms) : 97, 101
section CallTarget+Inlining+NGEN
This PR (8777) - mean (828ms) : 785, 871
master - mean (821ms) : 782, 860
HttpMessageHandler (.NET Framework 4.8)gantt
title Execution time (ms) HttpMessageHandler (.NET Framework 4.8)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (8777) - mean (196ms) : 188, 204
master - mean (200ms) : 192, 207
section Bailout
This PR (8777) - mean (200ms) : 193, 206
master - mean (203ms) : 198, 208
section CallTarget+Inlining+NGEN
This PR (8777) - mean (1,188ms) : 1151, 1225
master - mean (1,198ms) : 1157, 1240
HttpMessageHandler (.NET Core 3.1)gantt
title Execution time (ms) HttpMessageHandler (.NET Core 3.1)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (8777) - mean (282ms) : 275, 289
master - mean (284ms) : 277, 292
section Bailout
This PR (8777) - mean (282ms) : 276, 288
master - mean (286ms) : 281, 291
section CallTarget+Inlining+NGEN
This PR (8777) - mean (960ms) : 929, 991
master - mean (959ms) : 940, 978
HttpMessageHandler (.NET 6)gantt
title Execution time (ms) HttpMessageHandler (.NET 6)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (8777) - mean (276ms) : 268, 284
master - mean (279ms) : 274, 284
section Bailout
This PR (8777) - mean (280ms) : 273, 288
master - mean (278ms) : 274, 283
section CallTarget+Inlining+NGEN
This PR (8777) - mean (1,160ms) : 1126, 1195
master - mean (1,160ms) : 1125, 1196
HttpMessageHandler (.NET 8)gantt
title Execution time (ms) HttpMessageHandler (.NET 8)
dateFormat x
axisFormat %Q
todayMarker off
section Baseline
This PR (8777) - mean (275ms) : 268, 283
master - mean (276ms) : 270, 281
section Bailout
This PR (8777) - mean (275ms) : 270, 281
master - mean (277ms) : 273, 280
section CallTarget+Inlining+NGEN
This PR (8777) - mean (1,040ms) : 1004, 1075
master - mean (1,040ms) : 1003, 1078
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
BenchmarksBenchmark execution time: 2026-06-12 10:36:01 Comparing candidate commit 49a2f28 in PR branch Found 0 performance improvements and 0 performance regressions! Performance is the same for 72 metrics, 0 unstable metrics, 59 known flaky benchmarks, 67 flaky benchmarks without significant changes.
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ce3a40484a
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
ce3a404 to
4da569c
Compare
4da569c to
396789d
Compare
chrisnas
left a comment
There was a problem hiding this comment.
LGTM
maybe log per module when IsFileRangeValid() fails
## Summary of changes
Improve memory overhead of the `LibrariesCacheInfo`.
## Reason for change
`LibrariesCacheInfo` component caches ELF symbols to improve stack
walking. But this comes at a cost CPU + Memory.
Today (master)
```
[2026-06-11 10:58:49.687 | info | PId: 140997 | TId: 140997] LibrariesInfoCache stats:
[2026-06-11 10:58:49.687 | info | PId: 140997 | TId: 140997] Cache reloads: 10
[2026-06-11 10:58:49.687 | info | PId: 140997 | TId: 140997] Total CPU (worker): 42 ms
[2026-06-11 10:58:49.687 | info | PId: 140997 | TId: 140997] Libraries in cache: 21
[2026-06-11 10:58:49.687 | info | PId: 140997 | TId: 140997] Module regions: 18
[2026-06-11 10:58:49.687 | info | PId: 140997 | TId: 140997] Symbol entries: 27179
[2026-06-11 10:58:49.687 | info | PId: 140997 | TId: 140997] Memory current: 1410520 bytes
```
We can see a 42ms CPU usage and 1.4MB memory usage for 27179 symbols.
42ms of CPU over the lifetime of the application is totally negligible,
but 1.4MB leaves a mark.
This PR does 2 improvements:
- Replace std::function Deleters
- Compact FuncEntry for ARM64
With this PR
```
[2026-06-11 07:53:01.910 | info | PId: 20347 | TId: 20347] LibrariesInfoCache stats:
[2026-06-11 07:53:01.910 | info | PId: 20347 | TId: 20347] Cache reloads: 13
[2026-06-11 07:53:01.910 | info | PId: 20347 | TId: 20347] Total CPU (worker): 57 ms
[2026-06-11 07:53:01.910 | info | PId: 20347 | TId: 20347] Libraries in cache: 21
[2026-06-11 07:53:01.910 | info | PId: 20347 | TId: 20347] Module regions: 18
[2026-06-11 07:53:01.910 | info | PId: 20347 | TId: 20347] Symbol entries: 27179
[2026-06-11 07:53:01.910 | info | PId: 20347 | TId: 20347] Memory current: 565528 bytes
```
## Implementation details
- Replace std::unique_ptr<T, std::function<void(void*)>> with a trivial
deleter struct `PmrDeleter`
- Store function entries relative to their module base:
Works because: modules are always < 4GB (shared libraries mapped within
32-bit offset range from their base)
## Test coverage
## Other details
<!-- Fixes #{issue} -->
<!-- ⚠️ Note:
Where possible, please obtain 2 approvals prior to merging. Unless
CODEOWNERS specifies otherwise, for external teams it is typically best
to have one review from a team member, and one review from apm-dotnet.
Trivial changes do not require 2 reviews.
MergeQueue is NOT enabled in this repository. If you have write access
to the repo, the PR has 1-2 approvals (see above), and all of the
required checks have passed, you can use the Squash and Merge button to
merge the PR. If you don't have write access, or you need help, reach
out in the #apm-dotnet channel in Slack.
-->
Summary of changes
Improve memory overhead of the
LibrariesCacheInfo.Reason for change
LibrariesCacheInfocomponent caches ELF symbols to improve stack walking. But this comes at a cost CPU + Memory.Today (master)
We can see a 42ms CPU usage and 1.4MB memory usage for 27179 symbols. 42ms of CPU over the lifetime of the application is totally negligible, but 1.4MB leaves a mark.
This PR does 2 improvements:
With this PR
Implementation details
PmrDeleterWorks because: modules are always < 4GB (shared libraries mapped within 32-bit offset range from their base)
Test coverage
Other details