-
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
Open
rkennke
wants to merge
17
commits into
main
Choose a base branch
from
feat/native-mem-accounting
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
17 commits
Select commit
Hold shift + click to select a range
ba99ac9
feat(nativemem): categorized native-memory accounting — first cut
rkennke 1950e37
feat(nativemem): precise per-category max with bounded total
rkennke ab609a1
feat(nativemem): tag the big native-memory consumers
rkennke 958de87
feat(nativemem): tag DICTIONARY, remove CONTEXT
rkennke 40f6fcf
docs(nativemem): scope the async-signal-safety note to CALLTRACE
rkennke f6124f8
refactor(nativemem): rename CODECACHE category to NATIVE_SYMBOLS
rkennke 5b7cc8a
docs(nativemem): correct record() description (add + high-water CAS)
rkennke 279d97f
harden(nativemem): assert the non-negative and key-length invariants
rkennke 0036067
fix(nativemem): clamp emitted values; fix JFR_BUFFERS decrement ordering
rkennke 02a3c05
fix(profiler): two-phase calltrace resize; refresh native-lib counter…
rkennke f6cde90
feat(nativemem): account the perf _events array under NM_PERF
rkennke a2be664
test(nativemem): THREAD_LOCAL lifecycle coverage; copyright headers
rkennke 53fc7e2
fix(nativemem): balance deleteForTest; account frees after they happen
rkennke d4cad78
style(nativemem): record calltrace-buffer decrement after free(prev)
rkennke 9a8e4dd
style(nativemem): record perf _events decrement after free()
rkennke ae6358b
style(nativemem): record THREAD_LOCAL decrement after delete pt
rkennke 1a4f8ee
style(nativemem): record dictionary/arena decrements after free()
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,120 @@ | ||
| /* | ||
| * Copyright 2026 Datadog, Inc | ||
| * | ||
| * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| * you may not use this file except in compliance with the License. | ||
| * You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
| #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.