oracle/graal · critical · GraalError
Multiple garbage collectors selected: %s %s
Error message
Multiple garbage collectors selected: %s %s
What it means
getSelectedGC requires that exactly one HotSpotGC reports isSelected(this). If a second collector also reports selected, it throws GraalError('Multiple garbage collectors selected: A B'). Normally HotSpot guarantees a single -XX:+Use*GC, so this indicates contradictory VM flags or a broken/ported VM where several Use flags are simultaneously true.
Source
Thrown at compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/GraalHotSpotVMConfig.java:109
public boolean useSerialGC() {
return gc == HotSpotGraalRuntime.HotSpotGC.Serial;
}
public boolean useG1GC() {
return gc == HotSpotGraalRuntime.HotSpotGC.G1;
}
public final HotSpotGraalRuntime.HotSpotGC gc = getSelectedGC();
private HotSpotGraalRuntime.HotSpotGC getSelectedGC() throws GraalError {
HotSpotGraalRuntime.HotSpotGC selected = null;
for (HotSpotGraalRuntime.HotSpotGC value : HotSpotGraalRuntime.HotSpotGC.values()) {
if (value.isSelected(this)) {
if (!value.supported) {
throw new GraalError(value.name() + " garbage collector is not supported by Graal");
}
if (selected != null) {
throw new GraalError("Multiple garbage collectors selected: " + selected + " " + value);
}
selected = value;
}
}
if (selected == null) {
// Exactly one GC flag is guaranteed to be selected.
selected = HotSpotGraalRuntime.HotSpotGC.Serial;
}
return selected;
}
/**
* Determines if {@code -Xcomp} (or the equivalent thereof) was specified as a JVM argument.
*/
public final boolean xcompMode = !access.getFlag("UseInterpreter", Boolean.class);
public final boolean ropProtection = access.getFieldValue("VM_Version::_rop_protection", Boolean.class, "bool", false);
View on GitHub (pinned to a66e9ccd1d)
Solutions
- Leave exactly one GC-selection flag (let the VM default pick one) and remove duplicates from scripts, JAVA_OPTS, and JVM_OPTIONS env vars
- Query the effective GC with -XX:+PrintFlagsFinal -version | grep Use.*GC to see which flags ended up true
- If the VM really defaults multiple collectors to true, that is a VM build bug — fix the port/build
Example fix
# before java -XX:+UseG1GC -XX:+UseParallelGC -XX:+UseJVMCICompiler MyApp # after java -XX:+UseG1GC -XX:+UseJVMCICompiler MyApp
Defensive patterns
Strategy: validation
Validate before calling
// ensure exactly one Use*GC flag in the effective command line before enabling JVMCI
long gcFlags = Stream.of("UseG1GC", "UseParallelGC", "UseSerialGC", "UseZGC", "UseShenandoahGC").filter(f -> args.contains("-XX:+" + f)).count();
if (gcFlags > 1) throw new IllegalArgumentException("multiple GC flags"); Prevention
- Derive GC flags from a single source of truth in scripts
- Check -XX:+PrintFlagsFinal for accidentally-true Use*GC flags
- Never concatenate flag sets from multiple templates
When it happens
Trigger: Passing multiple -XX:+Use...GC flags (e.g. -XX:+UseG1GC -XX:+UseSerialGC) on a VM build that does not override later flags to false, or running a custom/modified HotSpot where more than one collector's selection check (flag or platform default) returns true; failure happens while GraalHotSpotVMConfig fields initialize.
Common situations: Benchmark scripts concatenating GC flags from different templates; custom JVM builds or ports with buggy flag defaults; flags injected both by JAVA_OPTS and the command line in container entrypoints.
Related errors
- Compiler configuration '%s' not found. Available configurati
- %s garbage collector is not supported by Graal
- too many decompiles: {} {}
- No options specified for MethodFilter:
- Option name must follow '<prefix>' prefix
AI-assisted analysis of oracle/graal@a66e9ccd1d (2026-08-14).
Data as JSON: /api/errors/f1bc69ec914d7b3e.
Report an issue: GitHub.