Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 10 additions & 5 deletions src/runtime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -383,9 +383,9 @@ export function setMaxHeap(bytes: number) {
explicitMaxHeap = true;
}
export function hasMaxHeap() { return explicitMaxHeap; }
let allocationCheck: { cap: number; step: number; allocated: number; baseline: number; enabled: boolean; usage: () => number; gc?: () => void } | null = null;
let allocationCheck: { cap: number; step: number; allocated: number; baseline: number; enabled: boolean; over: boolean; usage: () => number; gc?: () => void } | null = null;
export function setAllocationCheck(cap: number, usage: () => number, gc?: () => void) {
allocationCheck = { cap, step: Math.min(cap, Math.max(4 << 20, cap / 16)), allocated: 0, baseline: 0, enabled: false, usage, gc };
allocationCheck = { cap, step: Math.min(cap, Math.max(4 << 20, cap / 16)), allocated: 0, baseline: 0, enabled: false, over: false, usage, gc };
}
export function clearAllocationCheck() { allocationCheck = null; }
export function resetAllocationCheck() {
Expand All @@ -400,10 +400,15 @@ function allocated(bytes: number) {
check.allocated += bytes;
if (check.gc ? check.allocated < check.step : check.allocated <= check.cap) return;
check.allocated = 0;
if (check.usage() - check.baseline > check.cap) {
check.gc?.();
if (check.usage() - check.baseline > check.cap) throw new PendingThrow("java/lang/OutOfMemoryError", "Java heap space");
if (check.usage() - check.baseline > check.cap) check.gc?.();
// node frees array buffers after a collection, not during it, so one reading
// over the cap can still count garbage: throw on the second in a row
const over = check.usage() - check.baseline > check.cap;
if (over && check.over) {
check.over = false;
throw new PendingThrow("java/lang/OutOfMemoryError", "Java heap space");
}
check.over = over;
}
const ELEM_SIZE: Record<string, number> = { Z: 1, B: 1, C: 2, S: 2, I: 4, F: 4, J: 8, D: 8, L: 4 };

Expand Down
4 changes: 2 additions & 2 deletions test/java/HeapCap.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ public static void main(String[] args) {
try {
while (true) keep.add(new byte[256 * 1024]);
} catch (OutOfMemoryError e) {
System.out.println("OutOfMemoryError: " + e.getMessage());
// free the heap before printing: building the message allocates too
keep.clear();
System.gc();
System.out.println("OutOfMemoryError: " + e.getMessage());
}
for (int i = 0; i < 16; i++) keep.add(new byte[256 * 1024]);
System.out.println("continued");
Expand Down
Loading