Skip to content

test: coarsen ASan sampling rate/workload to stop nightly heap OOMs#653

Merged
jbachorik merged 2 commits into
mainfrom
jb/heap-nightly-oom
Jul 13, 2026
Merged

test: coarsen ASan sampling rate/workload to stop nightly heap OOMs#653
jbachorik merged 2 commits into
mainfrom
jb/heap-nightly-oom

Conversation

@jbachorik

@jbachorik jbachorik commented Jul 13, 2026

Copy link
Copy Markdown
Collaborator

What does this PR do?:
Coarsens the CPU/wall sampling interval and shrinks the driven workload, under ASan only, in four tests that were producing an unbounded number of profiler samples under ASan and then materializing a String stack trace for every single one of them:

  • MegamorphicCallTest (wall=100uswall=1ms; 1M → 100k iterations)
  • MetadataNormalisationTest (cpu=100uscpu=1ms; 100k → 10k iterations)
  • CTimerSamplerTest (cpu=100uscpu=1ms)
  • LightweightContextCpuTest (cpu=100uscpu=1ms)

Non-ASan behavior/rates are unchanged.

VtableReceiverFrameTest was initially included in this set but the change was reverted after review (discussion): it was never observed failing in CI, already sampled at a coarser cpu=1ms, and drives pure-Java virtual dispatch that ASan doesn't meaningfully slow down — stacking a 10x coarser interval with a 10x smaller workload risked starving its narrow .vtable stub()/vtable_receiver pattern search instead of fixing a real problem.

Motivation:
Nightly test-linux-glibc-aarch64 (*, asan) runs have been failing deterministically with Java heap space in the Gradle test executor for at least 4 consecutive nights (e.g. run 29223441349), always breaking at MegamorphicCallTest.testITableStubs().

Root cause: these tests use a very tight, fixed signal-based sampling interval (e.g. wall=100us) over a workload bounded by a fixed iteration count rather than a fixed wall-clock duration. Under ASan, signal handling itself is instrumented and much slower, so the same fixed-rate sampler collects a disproportionately larger number of samples (242,177 in the confirmed failing run) — and each test then builds a Java String stack trace for every sample to search for a substring, which exhausts the ASan test JVM's -Xmx1024m heap.

Two prior fixes (#632 forkEvery, #640 raising -Xmx 512m→1024m) only widened the margin without bounding the sample count, so the flake persisted. This applies the pattern already established for BoundMethodHandleProfilerTest (#630/#533): sample coarser and shrink the workload specifically under isAsan().

I audited every other test using a similarly tight sampling interval; the four listed above are the ones confirmed or strongly suspected to combine a tight interval, an iteration-bounded (not time-bounded) workload, and full per-sample materialization, without a countervailing reason (like VtableReceiverFrameTest's) to leave them alone.

Additional Notes:
N/A

How to test the change?:
Ran :ddprof-test:compileTestJava to confirm the changes compile; the actual regression only reproduces under ASan on aarch64 in CI, so the real validation is the next few nightly Nightly Sanitized Run executions no longer failing with Java heap space.

For Datadog employees:

  • This PR doesn't touch any of that.
  • JIRA: N/A (ad hoc investigation, no ticket filed)

Unsure? Have a question? Request a review!

Fixed-interval CPU/wall sampling (100us/1ms) over an iteration-bounded
workload scales unboundedly under ASan (signal handling itself is
instrumented), and each test materializes a String per sample, OOMing
the ASan test-runner heap. Sample coarser and shrink the workload under
isAsan(), matching the pattern already used in BoundMethodHandleProfilerTest.
@jbachorik jbachorik marked this pull request as ready for review July 13, 2026 10:46
@jbachorik jbachorik requested a review from a team as a code owner July 13, 2026 10:46

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 869ba8d074

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread ddprof-test/src/test/java/com/datadoghq/profiler/cpu/VtableReceiverFrameTest.java Outdated
@dd-octo-sts

dd-octo-sts Bot commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

CI Test Results

Run: #29244926453 | Commit: e0f1ec4 | Duration: 14m 53s (longest job)

All 32 test jobs passed

Status Overview

JDK glibc-aarch64/debug glibc-amd64/debug musl-aarch64/debug musl-amd64/debug
8 - - -
8-ibm - - -
8-j9 - -
8-librca - -
8-orcl - - -
11 - - -
11-j9 - -
11-librca - -
17 - -
17-graal - -
17-j9 - -
17-librca - -
21 - -
21-graal - -
21-librca - -
25 - -
25-graal - -
25-librca - -

Legend: ✅ passed | ❌ failed | ⚪ skipped | 🚫 cancelled

Summary: Total: 32 | Passed: 32 | Failed: 0


Updated: 2026-07-13 11:56:47 UTC

Unlike the other tests here, this one was never observed failing in CI,
already samples at a coarser cpu=1ms, and drives pure-Java virtual
dispatch that ASan doesn't slow down — stacking a 10x coarser interval
with a 10x smaller workload risked starving the narrow vtable-receiver
stack-pattern search instead of fixing a real problem.
@dd-octo-sts

dd-octo-sts Bot commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Benchmark Results (commit 869ba8d)

Pipeline: https://gitlab.ddbuild.io/DataDog/apm-reliability/benchmarking-platform/-/pipelines/124278010 Commit: 869ba8d074ed9264c5a500afff25f93e67047bd8

⚠️ Significant outliers

  • 🟢 future-genetic (JDK 21): runtime -4.9% (2153→2047 ms)
Runtime details (per benchmark × JDK)
Benchmark JDK Latest Dev Δ (dev vs latest) Issues L/D
akka-uct 21 ✅ 10386 ms (21 iters) ✅ 10314 ms (21 iters) ≈ -0.7% (±11.1%) — / —
akka-uct 25 ✅ 8896 ms (24 iters) ✅ 8760 ms (24 iters) ≈ -1.5% (±9.9%) — / —
finagle-chirper 21 ✅ 5960 ms (33 iters) ✅ 6003 ms (33 iters) ≈ +0.7% (±25.4%) ⚠️ W:3 / ⚠️ W:3
finagle-chirper 25 ✅ 5473 ms (36 iters) ✅ 5491 ms (36 iters) ≈ +0.3% (±24.5%) ⚠️ W:3 / ⚠️ W:3
fj-kmeans 21 ✅ 2694 ms (70 iters) ✅ 2766 ms (67 iters) ≈ +2.7% (±2.8%) — / —
fj-kmeans 25 ✅ 2822 ms (66 iters) ✅ 2828 ms (66 iters) ≈ +0.2% (±2.6%) — / —
future-genetic 21 ✅ 2153 ms (87 iters) ✅ 2047 ms (90 iters) 🟢 -4.9% — / —
future-genetic 25 ✅ 2021 ms (92 iters) ✅ 2048 ms (90 iters) ≈ +1.3% (±2.8%) — / —
naive-bayes 21 ✅ 1326 ms (129 iters) ✅ 1266 ms (135 iters) ≈ -4.5% (±32%) — / —
naive-bayes 25 ✅ 1003 ms (170 iters) ✅ 1010 ms (169 iters) ≈ +0.7% (±31.7%) — / —
reactors 21 ✅ 16276 ms (15 iters) ✅ 16443 ms (15 iters) ≈ +1% (±8.6%) — / —
reactors 25 ✅ 18707 ms (15 iters) ✅ 18656 ms (15 iters) ≈ -0.3% (±4.1%) — / —
Internal counter details (ddprof)

ddprof internal counters, latest / dev (✅ = 0, · = unavailable):

Benchmark JDK Dropped rec Dropped jvmti Dropped trace Skipped WC AGCT fail Unwind fail
akka-uct 21 ✅ / ✅ ✅ / ✅ ✅ / 2 1952 / 2049 ✅ / ✅ ✅ / ✅
akka-uct 25 ✅ / ✅ ✅ / ✅ 2 / 1 2264 / 2187 ✅ / ✅ ✅ / ✅
finagle-chirper 21 ✅ / ✅ ✅ / ✅ 3 / 3 8544 / 8822 ✅ / ✅ ✅ / ✅
finagle-chirper 25 ✅ / ✅ ✅ / ✅ 2 / 1 8090 / 8333 ✅ / ✅ ✅ / ✅
fj-kmeans 21 ✅ / ✅ ✅ / ✅ 1 / 2 1279 / 1263 ✅ / ✅ ✅ / ✅
fj-kmeans 25 ✅ / ✅ ✅ / ✅ 2 / 1 1291 / 1283 ✅ / ✅ ✅ / ✅
future-genetic 21 ✅ / ✅ ✅ / ✅ 3 / 2 2901 / 2958 ✅ / ✅ ✅ / ✅
future-genetic 25 ✅ / ✅ ✅ / ✅ 1 / ✅ 2873 / 2840 ✅ / ✅ ✅ / ✅
naive-bayes 21 ✅ / ✅ ✅ / ✅ 2 / 5 3543 / 3578 ✅ / ✅ ✅ / ✅
naive-bayes 25 ✅ / ✅ ✅ / ✅ 6 / 5 3470 / 3481 ✅ / ✅ ✅ / ✅
reactors 21 ✅ / ✅ ✅ / ✅ 2 / ✅ 1592 / 1528 ✅ / ✅ ✅ / ✅
reactors 25 ✅ / ✅ ✅ / ✅ ✅ / ✅ 1897 / 1899 ✅ / ✅ ✅ / ✅

@dd-octo-sts

dd-octo-sts Bot commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Benchmark Results (commit 1f3b41e)

Pipeline: https://gitlab.ddbuild.io/DataDog/apm-reliability/benchmarking-platform/-/pipelines/124281533 Commit: 1f3b41efee20a4547d19f0d69d6fe356b941f594

✅ Within expected boundaries

No significant runtime deltas (all within run-to-run noise) and no internal-counter outliers.

Runtime details (per benchmark × JDK)
Benchmark JDK Latest Dev Δ (dev vs latest) Issues L/D
akka-uct 21 ✅ 10272 ms (21 iters) ✅ 10414 ms (21 iters) ≈ +1.4% (±10.9%) — / —
akka-uct 25 ✅ 8895 ms (24 iters) ✅ 8932 ms (24 iters) ≈ +0.4% (±10.6%) — / —
finagle-chirper 21 ✅ 5950 ms (33 iters) ✅ 6009 ms (33 iters) ≈ +1% (±25%) ⚠️ W:3 / ⚠️ W:3
finagle-chirper 25 ✅ 5437 ms (36 iters) ✅ 5490 ms (36 iters) ≈ +1% (±24.8%) ⚠️ W:3 / ⚠️ W:3
fj-kmeans 21 ✅ 2726 ms (68 iters) ✅ 2715 ms (69 iters) ≈ -0.4% (±2.8%) — / —
fj-kmeans 25 ✅ 2837 ms (66 iters) ✅ 2836 ms (66 iters) ≈ -0% (±2.6%) — / —
future-genetic 21 ✅ 2111 ms (88 iters) ✅ 2091 ms (89 iters) ≈ -0.9% (±2.7%) — / —
future-genetic 25 ✅ 2084 ms (90 iters) ✅ 2098 ms (89 iters) ≈ +0.7% (±2.6%) — / —
naive-bayes 21 ✅ 1276 ms (134 iters) ✅ 1271 ms (135 iters) ≈ -0.4% (±32.5%) — / —
naive-bayes 25 ✅ 1019 ms (168 iters) ✅ 1013 ms (169 iters) ≈ -0.6% (±31.9%) — / —
reactors 21 ✅ 15712 ms (15 iters) ✅ 16726 ms (15 iters) ≈ +6.5% (±7.2%) — / —
reactors 25 ✅ 18585 ms (15 iters) ✅ 18458 ms (15 iters) ≈ -0.7% (±4.5%) — / —
Internal counter details (ddprof)

ddprof internal counters, latest / dev (✅ = 0, · = unavailable):

Benchmark JDK Dropped rec Dropped jvmti Dropped trace Skipped WC AGCT fail Unwind fail
akka-uct 21 ✅ / ✅ ✅ / ✅ 1 / 3 1987 / 1862 ✅ / ✅ ✅ / ✅
akka-uct 25 ✅ / ✅ ✅ / ✅ 2 / 1 2415 / 2298 ✅ / ✅ ✅ / ✅
finagle-chirper 21 ✅ / ✅ ✅ / ✅ 3 / 1 8700 / 8493 ✅ / ✅ ✅ / ✅
finagle-chirper 25 ✅ / ✅ ✅ / ✅ 1 / 2 8291 / 8325 ✅ / ✅ ✅ / ✅
fj-kmeans 21 ✅ / ✅ ✅ / ✅ 2 / 2 1276 / 1254 ✅ / ✅ ✅ / ✅
fj-kmeans 25 ✅ / ✅ ✅ / ✅ 4 / ✅ 1283 / 1293 ✅ / ✅ ✅ / ✅
future-genetic 21 ✅ / ✅ ✅ / ✅ ✅ / ✅ 2990 / 2975 ✅ / ✅ ✅ / ✅
future-genetic 25 ✅ / ✅ ✅ / ✅ 4 / 1 2905 / 2831 ✅ / ✅ ✅ / ✅
naive-bayes 21 ✅ / ✅ ✅ / ✅ 5 / 4 3556 / 3505 ✅ / ✅ ✅ / ✅
naive-bayes 25 ✅ / ✅ ✅ / ✅ 4 / 10 3507 / 3454 ✅ / ✅ ✅ / ✅
reactors 21 ✅ / ✅ ✅ / ✅ 2 / 2 1578 / 1756 ✅ / ✅ ✅ / ✅
reactors 25 ✅ / ✅ ✅ / ✅ ✅ / ✅ 1952 / 1843 ✅ / ✅ ✅ / ✅

@jbachorik jbachorik merged commit 6d392a7 into main Jul 13, 2026
181 of 182 checks passed
@jbachorik jbachorik deleted the jb/heap-nightly-oom branch July 13, 2026 12:03
@github-actions github-actions Bot added this to the 1.47.0 milestone Jul 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant