Repository navigation
Cap the whole Java heap in browsers with a maxHeap option - #57
Conversation
|
Warning Review limit reachedYou've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Next included review available in 37 minutes. View limit details
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. |
There was a problem hiding this comment.
This PR adds a maxHeap option to cheerpjInit() that caps the total Java heap in browsers, mirroring Node's -Xmx behavior. The browser worker tracks live memory by counting arrays ≥4 KB from allocation until FinalizationRegistry finalizers report collection. When the sum exceeds the cap, a 256 MB throwaway ArrayBuffer nudges Chromium to collect, and the VM pauses threads; OutOfMemoryError is thrown after 100 ms of finalizer quiet or 1 s total over the cap. Validation accepts bytes or -Xmx-style strings (k/m/g, 2 MB 1 GB). Documentation and tests are included.
review-bot, model nvidia/nemotron-3-ultra-550b-a55b:free, verdict approve
Pages can now cap the Java heap with
cheerpjInit({ maxHeap: "256m" }). Before, the browser capped only a single array, so a program that kept allocating grew until the tab died. Under Node,-Xmxalready caps the whole heap.maxHeaptakes bytes or a size withk,morg, as-Xmxdoes: at least 2 MB, at most 1 GB. It sets whatRuntime.maxMemory()reports, and CheerpJ has no such option.How the browser measures the heap:
performance.memoryandmeasureUserAgentSpecificMemory()are missing, so the VM counts live memory itself. It adds up arrays of 4 KB or more from allocation until aFinalizationRegistrycallback reports them collected.gc(), so a dropped array keeps counting until the engine collects it. Over the cap, the VM allocates a throwaway 256 MBArrayBuffer, which makes Chromium collect, and pauses its threads a few milliseconds at a time. It throwsOutOfMemoryError: Java heap spaceonce finalizers have been quiet for 100 ms with the sum still over the cap, or after 1 s over. A smaller 64 MB push gave false errors.FinalizationRegistry, or withoutmaxHeap, only the per-array cap applies.Results in headless Chromium, filling a list with 256 KB arrays until the error, clearing it, churning garbage, and filling again, 8 rounds per cap:
maxHeapThe error came about 0.1 s after the cap. Allocation-heavy code shows no cost from the counting: 400k 8 KB arrays plus 6M small objects ran in 1170 ms on master and 1180 ms here, within the 1069 to 1367 ms spread. The browser self-test's javac compile showed no difference beyond its run-to-run spread.
Tests:
test/heapcheck.test.tscovers the counting and the lazy check.pnpm typecheckandpnpm testpass.docs/browser.mdhas a "Memory limit" section.Noticed, not fixed: