Core Java

G1 Isn’t the Only Default That Changed: A Java 25→26 Migration Reality Check

The real driver behind this migration isn’t curiosity, it’s a September 2026 licensing cliff. And what actually breaks isn’t quite what most changelogs lead with.

If your team is still on Java 21, the reason you’re reading this probably isn’t “we’ve been meaning to modernize.” It’s that Oracle’s free, No-Fee Terms and Conditions license for JDK 21 runs out in September 2026, one year after JDK 25 shipped, and after that date every further JDK 21 update requires a paid subscription. As of this writing, that’s roughly five weeks away. That deadline is quietly forcing a lot of migrations that would otherwise have been scheduled for “sometime next quarter,” and it means most teams making this jump aren’t doing a tidy 25-to-26 bump. They’re jumping straight from 21, which means absorbing every default change from JDK 22 through 26 in one go, whether or not each individual change technically landed in the version number they’re aiming for.

A correction worth making up front: a few specific claims about “what changed in 26” circulate in migration checklists that don’t hold up against the actual JEPs. This piece checks each one against its source before including it, and flags the ones that are commonly misattributed.

The GC Default Confusion, Sorted Out

G1 has been Java’s default garbage collector since Java 9. What changed for this migration isn’t G1 becoming the default, it’s G1 getting meaningfully faster, and a further widening of where it’s the default that hasn’t shipped yet. JDK 26 ships JEP 522, which reduces the synchronization overhead between G1 and application threads to levels close to the much simpler Serial collector, a genuine throughput win with no configuration required.

JEP 523, “Make G1 the Default Garbage Collector in All Environments,” is not a JDK 26 change. It’s proposed and targeted to JDK 27. Today, on constrained machines with a single CPU or less than 1,792 MB of memory, the JVM still quietly falls back to the Serial collector unless you specify otherwise, exactly as it has since JEP 248 introduced that ergonomic rule back in JDK 9. If your team runs small containers or CI runners without an explicit -XX:+UseG1GC, you are not affected by this yet, but you will be on your very next major upgrade, so it’s worth benchmarking now rather than being surprised in a year.

The Real Breaking Change for Unsafe/Off-Heap Code

This is the one migration checklists most often undersell, and it’s the one most likely to produce an actual production incident. sun.misc.Unsafe‘s memory-access methods have been on a five-year, publicly telegraphed removal schedule, and JDK 26 is where that schedule stops being theoretical.

  • JDK 23: The memory-access methods were terminally deprecated via JEP 471, with a --sun-misc-unsafe-memory-access flag added so teams could test the impact ahead of time.
  • JDK 24: Per JEP 498, the default flipped from allow to warn. Any code path touching these methods now logs a runtime warning by default.
  • JDK 26: The default flips again, from warn to deny. Unsupported memory-access calls now throw exceptions by default, not warnings.
  • After JDK 26: The methods are removed outright, and the compatibility flag itself stops being honored.

sun.misc.Unsafe Memory-Access Enforcement, by JDK Version

Default behavior of unsupported Unsafe memory-access methods at each release, absent any explicit flag.Source: JEP 498 and Oracle’s “Integrity by Default” roadmap

The practical danger here isn’t your own code, since most application developers never call sun.misc.Unsafe directly. It’s your dependencies. Serialization libraries, older caching frameworks, and some high-performance data structures have historically leaned on these methods for speed. Run your test suite on JDK 26 with --sun-misc-unsafe-memory-access=warn explicitly set before you go anywhere near deny, so you can see exactly which of your dependencies are still exposed, and check for updated versions before the exception, not after it.

Compact Object Headers: Not Default Yet, But Getting Easier to Enable by Accident

The other memory-layout change worth understanding is compact object headers, and here the corrective note runs the other way: this feature is not on by default in either 25 or 26. It shrinks the standard HotSpot object header from 96 or 128 bits down to a single 64-bit word, a meaningful win in object-heavy or memory-constrained workloads. It shipped experimentally as JEP 450 in JDK 24, then graduated to a supported, non-experimental product feature via JEP 519 in JDK 25, which means the -XX:+UnlockExperimentalVMOptions flag is no longer required, just -XX:+UseCompactObjectHeaders on its own.

That’s precisely what makes it risky during a migration: it’s now one easily copy-pasted flag away from being enabled, often lifted straight from a performance-tuning blog post without anyone on the team registering that it changes the object memory layout. Anything doing pointer arithmetic against assumed header offsets, using tools like JOL to inspect memory layout, or relying on native code that reads object headers directly, needs to be re-verified under this flag before anyone enables it, because JOL’s own older releases have been documented to misread the new 8-byte layout entirely, reporting phantom fields that don’t exist. There’s also a further JEP, 534, proposing to make compact headers the default outright in a future release, so this is worth testing now even if you have no plans to flip the flag today.

Windows 32-bit: Already Gone, Just New to You

Here’s the second common misattribution: Windows 32-bit x86 support wasn’t removed as part of this migration cycle either. JEP 479 removed the Windows 32-bit x86 port back in JDK 24, alongside JEP 501 deprecating the broader 32-bit x86 port on other platforms. If you’re jumping straight from JDK 21, this will genuinely be new to you, not because it happened during your migration window, but because you skipped three releases where it already happened to everyone else. Any build infrastructure, CI runner, or embedded deployment target still assuming a 32-bit Windows JRE needs to move to a 64-bit target or stay pinned to JDK 21 under a paid subscription; there is no 32-bit Windows path forward on any currently supported release.

The Clock Actually Driving This

None of the above matters if your team never gets off JDK 21 in time. Oracle’s NFTC licensing model gives every LTS release free updates for exactly one year past the next LTS release, a pattern that’s held since JDK 17.

Free (NFTC) Update Window by LTS Release

JDK 21’s window is the one closing now; JDK 25’s window, by the same pattern, opens the clock on the next migration.Source: Oracle Java SE Downloads and Licensing FAQ

JDK 21’s free window closes in September 2026. Every subsequent JDK 21 update after that point is licensed under the paid OTN agreement, the same terms that already apply to JDK 17, 11, and 8. Migrating to JDK 25 (the current LTS) buys free updates all the way to September 2028, which is the real, non-technical reason this migration is worth finishing properly rather than rushing.

At a Glance: What Actually Changed, and When

ChangeActually shipped inCommonly misattributed to
G1 default in constrained (low-memory/single-CPU) environmentsJDK 27 (proposed, JEP 523)JDK 26
G1 throughput/synchronization improvementJDK 26 (JEP 522)—
sun.misc.Unsafe memory-access default: warnJDK 24 (JEP 498)—
sun.misc.Unsafe memory-access default: deny (throws)JDK 26Often missed entirely in checklists
Compact object headers, product feature (opt-in)JDK 25 (JEP 519)Assumed to be default already
Windows 32-bit x86 port removedJDK 24 (JEP 479)JDK 25/26

Quick Checklist: Migrating Off JDK 21 Before the Cliff

  • Run your full test suite on the target JDK with --sun-misc-unsafe-memory-access=warn explicitly set, and audit every dependency that logs a warning before you go anywhere near the JDK 26 default of deny.
  • Benchmark your actual GC behavior on constrained CI runners and small containers now; the fallback to Serial GC is still active today and will change on your next major upgrade, not this one.
  • Grep your build and deployment scripts for any 32-bit Windows JRE reference; there’s no supported path forward for it past JDK 23.
  • Before enabling compact object headers for the memory savings, re-test any code that inspects object layout directly, including tools like JOL, which has documented compatibility gaps with the new 8-byte header.
  • Treat the September 2026 NFTC deadline as the real project deadline, not the JDK 26 feature list; landing on JDK 25 alone already buys you until 2028.

What We Have Learned

The migration teams are actually staring down this year isn’t a clean 25-to-26 point release, it’s a 21-to-current jump forced by a licensing deadline, which means every default change since JDK 22 lands at once regardless of which release note it technically belongs to. Sorting out the attribution matters in practice: G1 becoming the universal default is real but isn’t here until JDK 27, Windows 32-bit support has been gone since JDK 24, and compact object headers remain opt-in through JDK 26 even though they’re one easily-copied flag away from being switched on by accident.

The change most worth an actual audit is the one most checklists undersell, sun.misc.Unsafe’s memory-access methods moving from warnings to thrown exceptions by default in JDK 26, with full removal coming after it. None of this is a reason to delay. It’s a reason to test specifically for these four things, rather than assuming a green build on JDK 21 will stay green after the jump, with five weeks left on the clock before staying put stops being free.

Eleftheria Drosopoulou

Eleftheria is an Experienced Business Analyst with a robust background in the computer software industry. Proficient in Computer Software Training, Digital Marketing, HTML Scripting, and Microsoft Office, they bring a wealth of technical skills to the table. Additionally, she has a love for writing articles on various tech subjects, showcasing a talent for translating complex concepts into accessible content.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Oldest
Newest Most Voted
Back to top button