Stop the resource guardrail from killing the JVM - #9
Conversation
The nightly run's model checking job failed within a second of starting, on main, with no explanation printed. Two bugs, and the second is why the first was invisible. `ulimit -v` is the wrong instrument for a JVM. It reserves far more address space than it ever commits — compressed class space alone asks for a gigabyte before any heap — so a virtual ceiling sized to the intended heap stops it starting at all. It fails as "Could not allocate compressed class space", which reads like a memory shortage and is actually the guardrail. This never showed locally because the machine it was written on has enough RAM that a quarter of it left plenty of headroom; the CI runner has 16GB, so the quarter share was 4GB and the JVM could not start. The heap is capped with -Xmx instead, which is the JVM's own instrument and is precise about what it limits. `ulimit -v` still applies to native processes, where it does what it was meant to. The silence was separate. The failure path filtered TLC's output through grep, and a grep that matches nothing exits non-zero — which under `set -o pipefail` aborted the script before it printed anything. The one run that failed was the one run that explained nothing. It now prints the output unfiltered. Verified by reproducing the CI budget locally: passes at 3997MB, and a deliberately starved heap now reports "Too small maximum heap" rather than exiting mute. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Your trial has ended. Reactivate Greptile to resume code reviews.
|
Warning Review limit reached
Next review available in: 50 minutes Limit details: You’ve used the included review currently available. You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits within each organization. For paid Pro and Pro+ reviews, CodeRabbit uses a developer's included PR review attempts over the past 7 days to set the current hourly allowance. At typical activity levels, the full plan allowance applies. Higher sustained activity can lower the allowance until earlier attempts leave the 7-day window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
The first nightly run on main failed. Model checking died within a second and printed nothing; mutation testing and the simulation soak both passed.
Two bugs, and the second is why the first was invisible.
The guardrail killed the thing it was guarding
ulimit -vis the wrong instrument for a JVM. It reserves far more address space than it ever commits — compressed class space alone asks for a gigabyte before any heap — so a virtual ceiling sized to the intended heap stops it starting at all. It fails asCould not allocate compressed class space, which reads like a memory shortage and is actually the cap.It never showed locally. This machine has enough RAM that a quarter share left plenty of headroom; the CI runner has 16GB, so the quarter share was 4GB and the JVM could not initialise.
The heap is capped with
-Xmxnow, which is the JVM's own instrument and precise about what it limits.ulimit -vstill applies to native processes, where it does what it was meant to.The failure explained nothing
The failure path filtered TLC's output through
grep, and a grep that matches nothing exits non-zero — which underset -o pipefailaborted the script before printing. So the one run that failed was the one run with no diagnostic. It now prints the output unfiltered.Verified
Reproduced the CI budget locally rather than guessing:
The second is the point: a starved run now says why instead of exiting mute.