oracle/graal · warning · PermanentBailoutException

Out-of-memory during live set allocation of size %d

Error message

Out-of-memory during live set allocation of size %d

What it means

Thrown at the end of computeLocalLiveSets when building the per-block SparseBitSets (liveGen/liveKill/liveIn/liveOut) runs out of memory. Like the BitMap2D failure, the linear-scan lifetime analysis phase wraps the OutOfMemoryError into a PermanentBailoutException, reporting allocator.liveSetSize() so you can tell whether the method is truly too large or the JVM just lacked heap.

Source

Thrown at compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/lir/alloc/lsra/LinearScanLifetimeAnalysisPhase.java:287

                            op.visitEachOutput(defConsumer);
                        }
                    } // end of instruction iteration

                    BlockData blockSets = allocator.getBlockData(block);
                    blockSets.liveGen = new SparseBitSet(liveGenScratch);
                    blockSets.liveKill = new SparseBitSet(liveKillScratch);
                    blockSets.liveIn = new SparseBitSet();
                    blockSets.liveOut = new SparseBitSet();

                    if (debug.isLogEnabled()) {
                        debug.log("liveGen  B%d %s", block.getId(), blockSets.liveGen);
                        debug.log("liveKill B%d %s", block.getId(), blockSets.liveKill);
                    }

                }
            } // end of block iteration
        } catch (OutOfMemoryError oom) {
            throw new PermanentBailoutException(oom, "Out-of-memory during live set allocation of size %d", liveSize);
        }
    }

    private boolean verifyTemp(SparseBitSet liveKill, Value operand) {
        if (allocator.isDetailedAsserts()) {
            /*
             * Fixed intervals are never live at block boundaries, so they need not be processed in
             * live sets. Process them only in debug mode so that this can be checked
             */
            if (isRegister(operand)) {
                if (allocator.isProcessed(operand)) {
                    liveKill.set(getOperandNumber(operand));
                }
            }
        }
        return true;
    }

View on GitHub (pinned to a66e9ccd1d)

Solutions

  1. Increase available heap (-Xmx / reduce compilation-thread memory pressure) if the live-set size is plausible for the method.
  2. Split or simplify the giant method so its live sets shrink.
  3. As a workaround, exclude the method from Graal compilation via -XX:CompileCommand=exclude.
Defensive patterns

Strategy: fallback

Try / catch

// permanent bailout wrapping OutOfMemoryError; increase heap or shrink the method.
// The reported live-set size tells you which side of the tradeoff you are on.

Prevention

When it happens

Trigger: Any `new SparseBitSet(...)` inside the block-iteration loop throwing OutOfMemoryError while computing local live sets — methods with very large live-variable sets across many blocks (huge methods after inlining and LIR generation).

Common situations: Compiling mega-methods under a memory-capped JVM; containers with low heap limits; Graal compilation threads competing for memory with a big application heap — the reported live-set size versus actual -Xmx tells you which case you are in.

Related errors


AI-assisted analysis of oracle/graal@a66e9ccd1d (2026-08-14). Data as JSON: /api/errors/0f02f9c7a2faafc7. Report an issue: GitHub.