-
Notifications
You must be signed in to change notification settings - Fork 12
feat(nativemem): categorized native-memory accounting — first cut #669
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
19 commits
Select commit
Hold shift + click to select a range
61e1d75
feat(nativemem): categorized native-memory accounting — first cut
rkennke 49c99da
feat(nativemem): precise per-category max with bounded total
rkennke da03a78
feat(nativemem): tag the big native-memory consumers
rkennke f51aa21
feat(nativemem): tag DICTIONARY, remove CONTEXT
rkennke 2b4b811
docs(nativemem): scope the async-signal-safety note to CALLTRACE
rkennke 6a9d6f0
refactor(nativemem): rename CODECACHE category to NATIVE_SYMBOLS
rkennke 7d93828
docs(nativemem): correct record() description (add + high-water CAS)
rkennke cbffe77
harden(nativemem): assert the non-negative and key-length invariants
rkennke 10f608a
fix(nativemem): clamp emitted values; fix JFR_BUFFERS decrement ordering
rkennke 69a5087
fix(profiler): two-phase calltrace resize; refresh native-lib counter…
rkennke 44a57d3
feat(nativemem): account the perf _events array under NM_PERF
rkennke 12ba784
test(nativemem): THREAD_LOCAL lifecycle coverage; copyright headers
rkennke ab07edc
fix(nativemem): balance deleteForTest; account frees after they happen
rkennke de24185
style(nativemem): record calltrace-buffer decrement after free(prev)
rkennke 21c6823
style(nativemem): record perf _events decrement after free()
rkennke d457b52
style(nativemem): record THREAD_LOCAL decrement after delete pt
rkennke 1194e30
style(nativemem): record dictionary/arena decrements after free()
rkennke 3bc4b03
test(nativemem): smoke-test the aggregate NM accounting counters
rkennke 9ebd615
style(nativemem): use the short-form license header
rkennke File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,109 @@ | ||
| /* | ||
| * Copyright 2026, Datadog, Inc. | ||
| * SPDX-License-Identifier: Apache-2.0 | ||
| */ | ||
|
Copilot marked this conversation as resolved.
|
||
| #include "nativeMem.h" | ||
|
|
||
| volatile long long NativeMem::_live[NM_NUM_CATEGORIES] = {}; | ||
| volatile long long NativeMem::_max[NM_NUM_CATEGORIES] = {}; | ||
| long long NativeMem::_window[NM_NUM_CATEGORIES][NativeMem::WINDOW] = {}; | ||
| long long NativeMem::_total_window[NativeMem::WINDOW] = {}; | ||
| int NativeMem::_window_pos = 0; | ||
| int NativeMem::_window_count = 0; | ||
| long long NativeMem::_avg[NM_NUM_CATEGORIES] = {}; | ||
| long long NativeMem::_total_avg = 0; | ||
| long long NativeMem::_total_max_observed = 0; | ||
|
|
||
| long long NativeMem::liveTotal() { | ||
| long long total = 0; | ||
| for (int c = 0; c < NM_NUM_CATEGORIES; c++) { | ||
| // Clamp per-category negatives to 0 (see sample()): the total is exported | ||
| // as an unsigned varint, so a stray negative would otherwise serialize as a | ||
| // huge value and corrupt the counter stream. | ||
| long long v = load(_live[c]); | ||
| if (v > 0) { | ||
| total += v; | ||
| } | ||
| } | ||
| return total; | ||
| } | ||
|
|
||
| long long NativeMem::maxTotal() { | ||
| long long total = 0; | ||
| for (int c = 0; c < NM_NUM_CATEGORIES; c++) { | ||
| total += load(_max[c]); | ||
| } | ||
| return total; | ||
| } | ||
|
|
||
| void NativeMem::sample() { | ||
| long long total = 0; | ||
| for (int c = 0; c < NM_NUM_CATEGORIES; c++) { | ||
| long long v = load(_live[c]); | ||
| // A category's live bytes are never negative under correct pairing (asserted | ||
| // in record()). This clamp is a release-mode safety net: should an accounting | ||
| // bug slip past the assert under NDEBUG, it keeps a negative from skewing the | ||
| // window average and total rather than propagating garbage. | ||
| if (v < 0) { | ||
| v = 0; | ||
| } | ||
| _window[c][_window_pos] = v; | ||
| total += v; | ||
|
rkennke marked this conversation as resolved.
|
||
| } | ||
|
|
||
| // The per-category peaks are maintained precisely at allocation time by | ||
| // record(); here we only track the largest observed total. Note `total` is a | ||
| // non-atomic sum of the per-category gauges read moments apart, so it is an | ||
| // approximate sampled figure, not a strict instantaneous total. | ||
| _total_window[_window_pos] = total; | ||
| if (total > _total_max_observed) { | ||
| _total_max_observed = total; | ||
| } | ||
|
|
||
| _window_pos = (_window_pos + 1) % WINDOW; | ||
| if (_window_count < WINDOW) { | ||
| _window_count++; | ||
| } | ||
|
|
||
| for (int c = 0; c < NM_NUM_CATEGORIES; c++) { | ||
| long long sum = 0; | ||
| for (int i = 0; i < _window_count; i++) { | ||
| sum += _window[c][i]; | ||
| } | ||
| _avg[c] = sum / _window_count; | ||
| } | ||
|
|
||
| long long total_sum = 0; | ||
| for (int i = 0; i < _window_count; i++) { | ||
| total_sum += _total_window[i]; | ||
| } | ||
| _total_avg = total_sum / _window_count; | ||
| } | ||
|
|
||
| void NativeMem::reset() { | ||
| for (int c = 0; c < NM_NUM_CATEGORIES; c++) { | ||
| store(_live[c], (long long)0); | ||
| store(_max[c], (long long)0); | ||
| _avg[c] = 0; | ||
| for (int i = 0; i < WINDOW; i++) { | ||
| _window[c][i] = 0; | ||
| } | ||
| } | ||
| for (int i = 0; i < WINDOW; i++) { | ||
| _total_window[i] = 0; | ||
| } | ||
| _window_pos = 0; | ||
| _window_count = 0; | ||
| _total_avg = 0; | ||
| _total_max_observed = 0; | ||
| } | ||
|
|
||
| const char *NativeMem::categoryName(NativeMemCategory category) { | ||
| #define X_NM_NAME(a, b) b, | ||
| static const char *const names[] = {DD_NATIVE_MEM_CATEGORY_TABLE(X_NM_NAME)}; | ||
| #undef X_NM_NAME | ||
| if (category < 0 || category >= NM_NUM_CATEGORIES) { | ||
| return "unknown"; | ||
| } | ||
| return names[category]; | ||
| } | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.