<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://inside.java/feed.xml" rel="self" type="application/atom+xml" /><link href="https://inside.java/" rel="alternate" type="text/html" /><updated>2026-03-06T06:30:38+00:00</updated><id>https://inside.java/feed.xml</id><title type="html">insidejava</title><subtitle>News and views from members of the Java team at Oracle</subtitle><entry><title type="html">Episode 49 “LazyConstants in JDK 26” [IJN]</title><link href="https://inside.java/2026/03/06/podcast-049/" rel="alternate" type="text/html" title="Episode 49 “LazyConstants in JDK 26” [IJN]" /><published>2026-03-06T00:00:00+00:00</published><updated>2026-03-06T00:00:00+00:00</updated><id>https://inside.java/2026/03/06/Podcast-049</id><content type="html" xml:base="https://inside.java/2026/03/06/podcast-049/"><![CDATA[<p><img class="webfeedsFeaturedVisual" style="display: none;" src="/images/thumbnail/ChadMic.jpg?397501432" /></p>

<p><br /></p>

<iframe title="Libsyn Player" style="border: none" src="//html5-player.libsyn.com/embed/episode/id/40338450/height/90/theme/custom/thumbnail/yes/direction/forward/render-playlist/no/custom-color/000000/" height="90" width="100%" scrolling="no"></iframe>

<p><br /></p>

<p>Lazily initializing fields in Java is error-prone and undermines constant-folding. JDK 26 comes with JEP 526, which previews <code class="language-plaintext highlighter-rouge">LazyConstant</code>, a type that lazily initializes a value through a given <code class="language-plaintext highlighter-rouge">Supplier</code>. It executes that supplier at most once successfully and then assigns the value to a field annotated with <code class="language-plaintext highlighter-rouge">@Stable</code>, which allows constant folding. This API is also a poster child for how OpenJDK develops and evolves features.</p>

<p>Links:</p>
<ul>
  <li><a href="https://jdk.java.net/26/">JDK 26</a></li>
  <li><a href="https://openjdk.org/jeps/526">JEP 526</a></li>
  <li><a href="https://openjdk.org/jeps/8376595">JEP Draft for Lazy Constants in JDK 27</a></li>
  <li><a href="https://www.youtube.com/watch?v=bdHkbEIdBAs">Inside Java Newscast #101 on reflective final field mutation</a></li>
  <li><a href="https://inside.java/2025/06/10/podcast-037/">Inside Java Podcast #37 with Per Minborg - Efficient Initialization Using Stable Values</a></li>
  <li><a href="https://www.youtube.com/watch?v=bE1bRbZzQ_k">Inside Java Podcast #42 with John Rose - From Sumatra to Panama, from Babylon to Valhalla</a></li>
</ul>

<p><br />
Make sure to also check the <strong>Duke’s Corner podcast</strong> on <a href="https://dev.java/duke/corner/">dev.java</a>.</p>

<p><br /></p>

<h3 id="additional-resources">Additional resources</h3>

<ul>
  <li><a href="https://inside.java">Inside.java</a> : News and views from members of the Java team at Oracle</li>
  <li><a href="https://dev.java">Dev.java</a> : The Destination for Java Developers</li>
  <li><a href="https://openjdk.java.net/">OpenJDK</a></li>
  <li><a href="https://www.oracle.com/java/">Oracle Java</a></li>
</ul>

<p>For more episodes, check out <a href="https://inside.java/podcast">Inside Java</a>, our <a href="https://www.youtube.com/playlist?list=PLX8CzqL3ArzV_hXbRevwzrXSMcGNzhxiZ">YouTube playlist</a>, and follow <a href="https://twitter.com/java">@Java</a> on Twitter.</p>

<p>Contact us <a href="https://inside.java/about/">here</a>.</p>]]></content><author><name>[&quot;NicolaiParlog&quot;]</name></author><category term="Core Libraries" /><category term="JDK 26" /><summary type="html"><![CDATA[Lazily initializing fields in Java is error-prone and undermines constant-folding. JDK 26 comes with JEP 526, which previews LazyConstant, a type that lazily initializes a value through a given Supplier but still allows constant-folding.]]></summary></entry><entry><title type="html">Java 26 is Shipping Soon - Inside Java Newscast #108</title><link href="https://inside.java/2026/03/05/newscast-108/" rel="alternate" type="text/html" title="Java 26 is Shipping Soon - Inside Java Newscast #108" /><published>2026-03-05T00:00:00+00:00</published><updated>2026-03-05T00:00:00+00:00</updated><id>https://inside.java/2026/03/05/Newscast-108</id><content type="html" xml:base="https://inside.java/2026/03/05/newscast-108/"><![CDATA[<div class="youtube-embed">
    <iframe src="https://www.youtube.com/embed/njfzpKH4K2A" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen=""></iframe>
</div>

<p><em>Java 26 is getting all packaged up to be shipped worldwide! As with every release of the JDK there are a number of new features, improvements, changes in behavior, and more that developers should be aware of before upgrading. In this episode of the Inside Java Newscast we will review all the noteworthy changes coming in Java 26 that will impact developers.</em></p>

<p><em>Make sure to check the <a href="https://www.youtube.com/watch?v=njfzpKH4K2A">show-notes</a>.</em></p>]]></content><author><name>[&quot;BillyKorando&quot;]</name></author><category term="JDK 26" /><summary type="html"><![CDATA[Java 26 is getting all packaged up to be shipped worldwide! As with every release of the JDK there are a number of new features, improvements, changes in behavior, and more that developers should be aware of before upgrading. In this episode of the Inside Java Newscast we will review all the noteworthy changes coming in Java 26 that will impact developers.]]></summary></entry><entry><title type="html">HTTP Client Updates in Java 26</title><link href="https://inside.java/2026/03/04/jdk-26-http-client/" rel="alternate" type="text/html" title="HTTP Client Updates in Java 26" /><published>2026-03-04T00:00:00+00:00</published><updated>2026-03-04T00:00:00+00:00</updated><id>https://inside.java/2026/03/04/jdk-26-http-client</id><content type="html" xml:base="https://inside.java/2026/03/04/jdk-26-http-client/"><![CDATA[<p>Java 26, which will be released on March 17th, will debut a number of changes to the <code class="language-plaintext highlighter-rouge">java.net.http.HttpClient</code>, which was <a href="https://openjdk.org/jeps/321">originally added in JDK 11</a>. In this article we will review these changes and how developers can take advantage of them, and what they might need to consider when upgrading to Java 26 and beyond.</p>

<h2 id="http3-support">HTTP/3 Support</h2>

<p><a href="https://openjdk.org/jeps/517">JEP 517</a> adds support for HTTP/3 to the <code class="language-plaintext highlighter-rouge">HttpClient</code>. It’s important to note that support is only be added, but the default will remain HTTP/2, which has been the case since the <code class="language-plaintext highlighter-rouge">HttpClient</code> was initially added in <a href="https://openjdk.org/jeps/321">JDK 11</a>.</p>

<p>The preferred protocol version can be set at the <code class="language-plaintext highlighter-rouge">HttpClient</code> level:</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">var</span> <span class="n">client</span> <span class="o">=</span> <span class="nc">HttpClient</span><span class="o">.</span><span class="na">newBuilder</span><span class="o">()</span>
                       <span class="o">.</span><span class="na">version</span><span class="o">(</span><span class="nc">HttpClient</span><span class="o">.</span><span class="na">Version</span><span class="o">.</span><span class="na">HTTP_3</span><span class="o">)</span>
                       <span class="o">.</span><span class="na">build</span><span class="o">();</span>
</code></pre></div></div>

<p>And at the <code class="language-plaintext highlighter-rouge">HttpRequest</code> level:</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">var</span> <span class="n">request</span> <span class="o">=</span> <span class="nc">HttpRequest</span><span class="o">.</span><span class="na">newBuilder</span><span class="o">(</span><span class="no">URI</span><span class="o">.</span><span class="na">create</span><span class="o">(</span><span class="s">"https://openjdk.org/"</span><span class="o">))</span>
                         <span class="o">.</span><span class="na">version</span><span class="o">(</span><span class="nc">HttpClient</span><span class="o">.</span><span class="na">Version</span><span class="o">.</span><span class="na">HTTP_3</span><span class="o">)</span>
                         <span class="o">.</span><span class="na">GET</span><span class="o">().</span><span class="na">build</span><span class="o">();</span>
</code></pre></div></div>

<p>The <code class="language-plaintext highlighter-rouge">HttpClient</code> offers options for navigating the transition between HTTP/1.1 and HTTP/2 to HTTP/3 covered below.</p>

<h3 id="connecting-to-http3-services">Connecting to HTTP/3 services</h3>

<p>Part of the reason for not setting HTTP/3 as the default for <code class="language-plaintext highlighter-rouge">HttpClient</code>, is because HTTP/3 uses a new transport protocol, <a href="https://en.wikipedia.org/wiki/QUIC">QUIC</a>, an update from the TCP protocol used by HTTP/1.1 and HTTP/2, and HTTP/3 is not as widely deployed as HTTP/1.1 or HTTP/2. However while QUIC offers many advantages, the addition of a new transport protocol does bring some complications. Specifically there’s no way to know which transport protocol is being used ahead of time. To that end, below are four strategies that can be used with the <code class="language-plaintext highlighter-rouge">HttpClient</code> that can handle working with HTTP/1.1, HTTP/2, and HTTP/3 services.</p>

<h4 id="send-a-http3-request-first">Send a HTTP/3 Request First</h4>

<p>HTTP/3 should be used when available, and with services migrating towards HTTP/3 an optimistic approach can be taken to attempt to connect using HTTP/3 first, and only fall back to HTTP/2 or HTTP/1.1 if a connection cannot be established. This can be done by <strong>not</strong> setting the protocol version at the client level, but setting it at the request level:</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">var</span> <span class="n">client</span> <span class="o">=</span> <span class="nc">HttpClient</span><span class="o">.</span><span class="na">newBuilder</span><span class="o">().</span><span class="na">build</span><span class="o">();</span>

<span class="kt">var</span> <span class="n">request</span> <span class="o">=</span> <span class="nc">HttpRequest</span><span class="o">.</span><span class="na">newBuilder</span><span class="o">(</span><span class="no">URI</span><span class="o">.</span><span class="na">create</span><span class="o">(</span><span class="s">"https://openjdk.org/"</span><span class="o">))</span>
                         <span class="o">.</span><span class="na">version</span><span class="o">(</span><span class="nc">HttpClient</span><span class="o">.</span><span class="na">Version</span><span class="o">.</span><span class="na">HTTP_3</span><span class="o">)</span>
                         <span class="o">.</span><span class="na">GET</span><span class="o">().</span><span class="na">build</span><span class="o">();</span>
</code></pre></div></div>

<h4 id="send-http3-and-http2-or-http11-requests-in-parallel">Send HTTP/3 and HTTP/2 or HTTP/1.1 Requests in Parallel</h4>

<p>Sending requests in serial, like in the above example, can increase latency, espeically when a fallback is likely. Alternatively HTTP/3 and HTTP/2 or HTTP/1.1 requests can be sent in parallel, and the first one that succeeds will be used. This can be accomplished by setting the preferred version to HTTP/3 at the client level, but <strong>not</strong> setting a preferred version at the request level:</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">var</span> <span class="n">client</span> <span class="o">=</span> <span class="nc">HttpClient</span><span class="o">.</span><span class="na">newBuilder</span><span class="o">()</span>
                       <span class="o">.</span><span class="na">version</span><span class="o">(</span><span class="nc">HttpClient</span><span class="o">.</span><span class="na">Version</span><span class="o">.</span><span class="na">HTTP_3</span><span class="o">)</span>
                       <span class="o">.</span><span class="na">build</span><span class="o">();</span>

<span class="kt">var</span> <span class="n">request</span> <span class="o">=</span> <span class="nc">HttpRequest</span><span class="o">.</span><span class="na">newBuilder</span><span class="o">(</span><span class="no">URI</span><span class="o">.</span><span class="na">create</span><span class="o">(</span><span class="s">"https://openjdk.org/"</span><span class="o">))</span>
                         <span class="o">.</span><span class="na">GET</span><span class="o">().</span><span class="na">build</span><span class="o">();</span>
</code></pre></div></div>

<h4 id="send-a-http2-or-http11-request-first-and-redirect-to-http3-if-available">Send a HTTP/2 or HTTP/1.1 Request First and Redirect to HTTP/3 if Available</h4>

<p>If it’s likely the service you are connecting to does <strong>not</strong> support HTTP/3, then a pessimistic approach could be taken, and send a HTTP/1.1 or HTTP/2 request first, and only switching to HTTP/3 if the serivce says its available. This can be done by setting the <code class="language-plaintext highlighter-rouge">Http3DiscoveryMode.ALT_SVC</code> option:</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">var</span> <span class="n">client</span> <span class="o">=</span> <span class="nc">HttpClient</span><span class="o">.</span><span class="na">newBuilder</span><span class="o">()</span>
                       <span class="o">.</span><span class="na">build</span><span class="o">();</span>

<span class="kt">var</span> <span class="n">request</span> <span class="o">=</span> <span class="nc">HttpRequest</span><span class="o">.</span><span class="na">newBuilder</span><span class="o">(</span><span class="no">URI</span><span class="o">.</span><span class="na">create</span><span class="o">(</span><span class="s">"https://openjdk.org/"</span><span class="o">))</span>
						 <span class="o">.</span><span class="na">setOption</span><span class="o">(</span><span class="nc">HttpOption</span><span class="o">.</span><span class="na">H3_DISCOVERY</span><span class="o">,</span> <span class="nc">Http3DiscoveryMode</span><span class="o">.</span><span class="na">ALT_SVC</span><span class="o">)</span>
						 <span class="o">.</span><span class="na">GET</span><span class="o">().</span><span class="na">build</span><span class="o">();</span>
</code></pre></div></div>

<h4 id="only-use-http3">Only Use HTTP/3</h4>

<p>The last strategy would be to only use HTTP/3 and not fall back if the server does not reply with HTTP/3. This can be done by setting the <code class="language-plaintext highlighter-rouge">Http3DiscoveryMode.HTTP_3_URI_ONLY</code> option:</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">var</span> <span class="n">client</span> <span class="o">=</span> <span class="nc">HttpClient</span><span class="o">.</span><span class="na">newBuilder</span><span class="o">()</span>
                       <span class="o">.</span><span class="na">build</span><span class="o">();</span>

<span class="kt">var</span> <span class="n">request</span> <span class="o">=</span> <span class="nc">HttpRequest</span><span class="o">.</span><span class="na">newBuilder</span><span class="o">(</span><span class="no">URI</span><span class="o">.</span><span class="na">create</span><span class="o">(</span><span class="s">"https://openjdk.org/"</span><span class="o">))</span>
						 <span class="o">.</span><span class="na">setOption</span><span class="o">(</span><span class="nc">HttpOption</span><span class="o">.</span><span class="na">H3_DISCOVERY</span><span class="o">,</span> <span class="nc">Http3DiscoveryMode</span><span class="o">.</span><span class="na">HTTP_3_URI_ONLY</span><span class="o">)</span>
						 <span class="o">.</span><span class="na">GET</span><span class="o">().</span><span class="na">build</span><span class="o">();</span>
</code></pre></div></div>

<h2 id="uploading-file-regions">Uploading File Regions</h2>

<p>A new static method, <code class="language-plaintext highlighter-rouge">java.net.HttpRequest.BodyPublishers.ofFileChannel(FileChannel chan, long position, long size)</code> has been added. <code class="language-plaintext highlighter-rouge">ofFileChannel(FileChannel chan, long position, long size)</code> allows for a specific region of a file to be uploaded. For large files, this can avoid having to read the entire file into memory, and can be leveraged to slice a file it chunks and uploaded in parallel.</p>

<p><a href="JDK-8329829">https://bugs.openjdk.org/browse/JDK-8329829</a></p>

<h2 id="signature-schemes-and-named-groups-usage-fix">Signature Schemes and Named Groups Usage Fix</h2>

<p>During the setup of new connections, <code class="language-plaintext highlighter-rouge">HttpClient</code> now uses the signature schemes and named groups configured on <code class="language-plaintext highlighter-rouge">SSLParameters</code>, like in the example below, when negotiating the TLS handshake. Previously these configured values were ignored.</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">final</span> <span class="nc">SSLParameters</span> <span class="n">sslParameters</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">SSLParameters</span><span class="o">();</span>
<span class="n">sslParameters</span><span class="o">.</span><span class="na">setNamedGroups</span><span class="o">(</span><span class="k">new</span> <span class="nc">String</span><span class="o">[]{</span><span class="n">namedGroup</span><span class="o">});</span>

<span class="nc">HttpClient</span><span class="o">.</span><span class="na">newBuilder</span><span class="o">()</span>
	<span class="o">.</span><span class="na">sslContext</span><span class="o">(</span><span class="n">sslBundle</span><span class="o">.</span><span class="na">createSslContext</span><span class="o">())</span>
	<span class="o">.</span><span class="na">sslParameters</span><span class="o">(</span><span class="n">sslParameters</span><span class="o">)</span>
	<span class="o">.</span><span class="na">build</span><span class="o">();</span>
</code></pre></div></div>

<p><a href="JDK-8367112">https://bugs.openjdk.org/browse/JDK-8367112</a></p>

<h2 id="timeout-update">Timeout Update</h2>

<p>The <code class="language-plaintext highlighter-rouge">HttpClient</code> request timeout set using <code class="language-plaintext highlighter-rouge">java.net.http.HttpRequest.Builder::timeout</code> previously applied only until the response headers were received. Its scope has now been extended to also cover the consumption of the response body, if present. In most cases this should align with expected behavior of canceling a long running connection, but if your application frequently deals with large response bodies and depends upon the previous behavior, you will need to update your timeout values accordingly.</p>

<p><a href="JDK-8208693">https://bugs.openjdk.org/browse/JDK-8208693</a></p>

<h2 id="content-length-removed-for-non-postput-requests">Content-Length Removed for non-POST/PUT Requests</h2>

<p>The <code class="language-plaintext highlighter-rouge">HttpClient</code> will no longer send a <code class="language-plaintext highlighter-rouge">Content-Length</code> header on HTTP/1.1 request for non-POST/PUT methods which contain no body. This follows <a href="https://www.rfc-editor.org/rfc/rfc9110.html#name-content-length">RFC9110 semantics</a>. If your application depends on the <code class="language-plaintext highlighter-rouge">Content-Length</code> header, it can be added using <code class="language-plaintext highlighter-rouge">HttpRequest.Builder</code>, and by updating the <code class="language-plaintext highlighter-rouge">jdk.httpclient.allowRestrictedHeaders</code> property to include <code class="language-plaintext highlighter-rouge">Content-Length</code>.</p>

<p><a href="JDK-8358942">https://bugs.openjdk.org/browse/JDK-8358942</a></p>

<h2 id="missing-file-exception-update">Missing File Exception Update</h2>

<p>Previously the <code class="language-plaintext highlighter-rouge">java.net.http.HttpRequest.BodyPublishers::ofFile(Path)</code> method could throw a <code class="language-plaintext highlighter-rouge">java.io.NoSuchFileException</code> if the provided <code class="language-plaintext highlighter-rouge">Path</code> was not associated with the default file system. This inconsistency has been removed by mapping these to <code class="language-plaintext highlighter-rouge">java.io.FileNotFoundException</code>, in line with the <code class="language-plaintext highlighter-rouge">ofFile(Path)</code> API specification.</p>

<p><a href="JDK-8358688">https://bugs.openjdk.org/browse/JDK-8358688</a></p>

<h2 id="max-age-updates">Max-Age Updates</h2>

<p><code class="language-plaintext highlighter-rouge">java.net.HttpCookie</code> has been updated to correctly return the value of <code class="language-plaintext highlighter-rouge">Max-Age</code> when when calling <code class="language-plaintext highlighter-rouge">getMaxAge()</code> for cookies that have both <code class="language-plaintext highlighter-rouge">Expires</code> and <code class="language-plaintext highlighter-rouge">Max-Age</code> attributes. This follows <a href="https://www.rfc-editor.org/rfc/rfc6265.html#section-5.2.2">RFC 6265</a> specifies that the <code class="language-plaintext highlighter-rouge">Max-Age</code> attribute should take precedence over the <code class="language-plaintext highlighter-rouge">Expires</code> attribute.</p>

<p><a href="JDK-8351983">https://bugs.openjdk.org/browse/JDK-8351983</a></p>

<p>Java 26 ended up being a pretty important release for <code class="language-plaintext highlighter-rouge">HttpClient</code> users. With HTTP/3 support being added as well as several other updates. If you’d like to learn more about the <code class="language-plaintext highlighter-rouge">HttpClient</code>, and all the other features coming in Java 26 and beyond, consider attending JavaOne March 17-19th in Redwood Shores, California. Tickets are on sale now as well as the full session list at: https://javaone.com.</p>]]></content><author><name>[&quot;BillyKorando&quot;]</name></author><category term="JDK 26" /><category term="Core Libraries" /><category term="Networking" /><summary type="html"><![CDATA[The HttpClient will be receiving several updates in Java 26, let's review these changes and what Java users can expect.]]></summary></entry><entry><title type="html">Quality Outreach Heads-up - JavaFX 27: Metal Is Now the Default Rendering Pipeline on macOS</title><link href="https://inside.java/2026/03/03/quality-heads-up/" rel="alternate" type="text/html" title="Quality Outreach Heads-up - JavaFX 27: Metal Is Now the Default Rendering Pipeline on macOS" /><published>2026-03-03T00:00:00+00:00</published><updated>2026-03-03T00:00:00+00:00</updated><id>https://inside.java/2026/03/03/Quality-Heads-Up</id><content type="html" xml:base="https://inside.java/2026/03/03/quality-heads-up/"><![CDATA[<p><img class="webfeedsFeaturedVisual" style="display: none;" src="/images/thumbnail/code.jpg" /></p>

<p><i>The <a href="https://wiki.openjdk.java.net/display/quality/Quality+Outreach">OpenJDK Quality Group</a> is promoting the testing of FOSS projects with OpenJDK builds as a way to improve the overall quality of the release. This heads-up is part of the <a href="https://mail.openjdk.org/pipermail/quality-discuss/">quality outreach</a> sent to the projects involved. To learn more about the program, and how-to join, please check <a href="https://wiki.openjdk.java.net/display/quality/Quality+Outreach">here</a>.</i></p>

<h2 id="metal-is-now-the-default-rendering-pipeline-on-macos">Metal Is Now the Default Rendering Pipeline on macOS</h2>

<p>On macOS, the default JavaFX rendering pipeline has been switched to Metal since JavaFX 27 Early Access (EA) build 3. Metal provides improved performance and better compatibility on modern hardware.</p>

<p>The Metal pipeline was implemented under <a href="https://bugs.openjdk.org/browse/JDK-8271024">JDK-8271024</a> in JavaFX 26 as an optional pipeline, with the OpenGL-based ES2 pipeline as the default. Starting with JavaFX 27 EA build 3, Metal is now the default rendering pipeline on macOS.</p>

<p>JavaFX 27 EA builds are now available for <a href="https://jdk.java.net/javafx27/">download</a> and testing. You can share your feedback on the <a href="https://mail.openjdk.org/mailman/listinfo/openjfx-dev">openjfx-dev list</a> (registration required), through <a href="https://bugs.openjdk.org/">JBS</a> or <a href="https://bugreport.java.com">bugreport.java.com</a>.</p>

<p>If you need to revert to the previous ES2 pipeline, you can do so by adding the option <code class="language-plaintext highlighter-rouge">-Dprism.order=es2</code> to your Java command.</p>

<hr />
<p>References to metal blogs published earlier:</p>
<ul>
  <li><a href="https://inside.java/2025/09/22/quality-heads-up/">Quality Outreach Heads-up - JavaFX 26: Temporary Switch to macOS Metal Rendering Pipeline</a></li>
  <li><a href="https://inside.java/2025/09/22/quality-heads-up/">Quality Outreach Heads-up - New macOS JavaFX Metal Early-Access builds</a></li>
</ul>

<center>~</center>]]></content><author><name>[&quot;AmbarishRapte&quot;]</name></author><category term="JDK 27" /><category term="Client" /><summary type="html"><![CDATA[This Heads-Up is part of the regular communication sent to the projects involved; it covers a change in the macOS JavaFX rendering pipeline.]]></summary></entry><entry><title type="html">Java 26 for DevOps</title><link href="https://inside.java/2026/03/02/jdk-26-rn-ops/" rel="alternate" type="text/html" title="Java 26 for DevOps" /><published>2026-03-02T00:00:00+00:00</published><updated>2026-03-02T00:00:00+00:00</updated><id>https://inside.java/2026/03/02/jdk-26-rn-ops</id><content type="html" xml:base="https://inside.java/2026/03/02/jdk-26-rn-ops/"><![CDATA[<p>With every release of Java comes updates to the underlying runtime, and how JVM applications can be administered and observed. In this article we will review changes to this area that are coming Java 26, which is scheduled for release on March 17th.</p>

<h2 id="ahead-of-time-computation-for-zgc-users">Ahead-of-Time Computation for ZGC Users</h2>

<p><a href="https://openjdk.org/jeps/516">JEP 516</a> Ahead-of-Time (AOT) Object Caching with Any GC, brings the benefits of AOT introduced in Java 24 (<a href="https://openjdk.org/jeps/483">JEP 483</a>) and 25 (JEPs <a href="https://openjdk.org/jeps/514">514</a> &amp; <a href="https://openjdk.org/jeps/515">515</a>), to Z Garbage Collector (ZGC) users. AOT improves the startup and warm up performance of Java applications, by storing information from a previous run of an application in a cache that can be accessed on subsequent runs. To learn more about AOT, <a href="https://youtu.be/V_Pls6B4_yg">watch my video on this subject</a>.</p>

<p><a href="https://openjdk.org/jeps/516">JEP 516</a></p>

<h2 id="g1-garbage-collector-updates">G1 Garbage Collector Updates</h2>

<p>G1, Java’s default garbage collector, remains under active development, and there are several notable changes coming in Java 26.</p>

<h3 id="g1-gc-improve-throughput-by-reducing-synchronization">G1 GC: Improve Throughput by Reducing Synchronization</h3>

<p>The throughput of the G1 garbage collector has been improved in Java 26 by reducing the frequency of synchronization with application threads. This was done by introducing a second card table allowing the optimizer and application threads to run freely. This also had the second order effect of reducing the write barriers in G1 from 50 intructions to 12.</p>

<p>Testing has shown that these changes have improved throughput by 5-15% percent, with applications that do heavy modification to object-reference fields seeing the most benefit. Additionally this new design is more efficent that the previous auxillry data structure, which resulted in a slight descrease in pause times. Lastly the second card table can in some cases slightly reduce memory overhead; each card table requiring about 2MB of native meory per 1GB of heap capacity. In cases where it does consume more memory than before, the difference is trivial.</p>

<p><a href="https://openjdk.org/jeps/522">JEP 522</a></p>

<h3 id="humongous-object-reclamation">Humongous Object Reclamation</h3>

<p>The G1 garbage collector now eagerly reclaims eligible humongous objects (objects occupying more than half a heap region) containing references.</p>

<p>This change allows for the prompt recovery of memory previously held by such objects, particularly if they are short-lived, improving garbage collection efficiency and reducing heap usage. Previously such humongous objects were only reclaimed during full gcs.</p>

<p>This change applies to both discrete humongous objects, as well as to humongous arrays of references (i.e. <code class="language-plaintext highlighter-rouge">Object[]</code>).</p>

<p><a href="https://bugs.openjdk.org/browse/JDK-8048180">JDK-8048180</a></p>

<h3 id="g1-overhead-limit">G1 Overhead Limit</h3>

<p>The G1 garbage collector now throws an <code class="language-plaintext highlighter-rouge">OutOfMemoryException</code> when the garbage collection overhead is more than the <code class="language-plaintext highlighter-rouge">GCTimeLimit</code> percent  (default <code class="language-plaintext highlighter-rouge">98</code>) and the free Java heap is less than the <code class="language-plaintext highlighter-rouge">GCHeapFreeLimit</code> percent  (default <code class="language-plaintext highlighter-rouge">2</code>) for five consecutive garbage collections. This can help prevent GC thrashing in such scenarios and mirrors the behavior implemented in the Parallel GC.</p>

<p>This feature is enabled by default. It can be disabled using the <code class="language-plaintext highlighter-rouge">-XX:-UseGCOverheadLimit</code> option.</p>

<p><a href="https://bugs.openjdk.org/browse/JDK-8212084">JDK-8212084</a></p>

<h3 id="transparent-huge-pages-support">Transparent Huge Pages Support</h3>

<p>G1 can again properly utilize Transparent Huge Pages (THP) on systems with the THP mode configured as <code class="language-plaintext highlighter-rouge">madvise</code>, this resolves an issue introduced in <a href="https://bugs.openjdk.org/browse/JDK-8345655">Java 25</a>. This issue has also been backported to 25.0.2.</p>

<p><a href="https://bugs.openjdk.org/browse/JDK-8366434">JDK-8366434</a></p>

<h2 id="jvm-flag-updates">JVM Flag Updates</h2>

<p>There are a number of updates to JVM flags in Java 26.</p>

<h3 id="initialrampercentage-default-value-removed">InitialRAMPercentage Default Value Removed</h3>

<p><code class="language-plaintext highlighter-rouge">InitialRAMPercentage</code> is being changed from 1.5625 (1/64) to 0. The previous default value was last set in 2007. At that time, the value of 1.5625 was a reasonable assumption, but as available system memory has increased, it can result in excessively large heap sizes. This could result in wasted resources and slower startup performance.</p>

<p>To address this the default value of <code class="language-plaintext highlighter-rouge">InitialRAMPercentage</code> has been removed (set to <code class="language-plaintext highlighter-rouge">0</code>), which matches with <code class="language-plaintext highlighter-rouge">MinHeapSize</code> and <code class="language-plaintext highlighter-rouge">InitialHeapSize</code>, which will default to using <a href="https://docs.oracle.com/en/java/javase/25/gctuning/ergonomics.html#GUID-DB4CAE94-2041-4A16-90EC-6AE3D91EC1F1">JVM ergonomics</a> for setting these values. Users could, if needed, set these values using <code class="language-plaintext highlighter-rouge">-Xms</code>. It is also still possible to set <code class="language-plaintext highlighter-rouge">InitialRAMPercentage</code> explicitly; <code class="language-plaintext highlighter-rouge">-XX: InitialRAMPercentage=[0.0-100]</code>.</p>

<p><a href="https://bugs.openjdk.org/browse/JDK-8371986">JDK-8371986</a></p>

<h3 id="server-and-client-flags-deprecated-for-removal">Server and Client Flags Deprecated for Removal</h3>

<p>The flags <code class="language-plaintext highlighter-rouge">AlwaysActAsServerClassMachine</code> and <code class="language-plaintext highlighter-rouge">NeverActAsServerClassMachine</code> are marked as deprecated for removal. The primary benefit of these flags was driving ergonomics for GC selection: G1 being used on server class machines, and Serial on client machines. However, with the future introduction of <a href="https://openjdk.org/jeps/523">JEP 523</a>, which makes G1 the default GC in all environments, there’s is little difference between the two JVM arguments.</p>

<p><a href="https://bugs.openjdk.org/browse/JDK-8370843">JDK-8370843</a></p>

<h3 id="aggressiveheap-deprecated-for-removal">AggressiveHeap Deprecated for Removal</h3>

<p>The flag <code class="language-plaintext highlighter-rouge">AggressiveHeap</code> has been marked as deprecated for removal. <code class="language-plaintext highlighter-rouge">AggressiveHeap</code> was originally added to satisfy specific benchmarks, but lacks transparency. If your application depended on the behavior of <code class="language-plaintext highlighter-rouge">AggressiveHeap</code>, you can recreate it with the following set of flags:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>-XX:+UseParallelGC -XX:+UseLargePages 
-XX:-ResizeTLAB -XX:TLABSize=256K 
-XX:YoungPLABSize=256K -XX:OldPLABSize=8K 
-XX:ThresholdTolerance=100
</code></pre></div></div>

<p>And additionally set the following flags to the relevant values based on your systems resources:</p>

<ul>
  <li><code class="language-plaintext highlighter-rouge">-Xmx</code> and <code class="language-plaintext highlighter-rouge">-Xms</code> to half the available physical memory</li>
  <li><code class="language-plaintext highlighter-rouge">-XX:NewSize</code> to 3/8 of available physical memory</li>
  <li><code class="language-plaintext highlighter-rouge">-XX:MaxNewSize</code> to the value of <code class="language-plaintext highlighter-rouge">-XX:NewSize</code></li>
</ul>

<p><a href="https://bugs.openjdk.org/browse/JDK-8370813">JDK-8370813</a></p>

<h3 id="maxram-deprecated-for-removal">MaxRAM Deprecated for Removal</h3>

<p>The <code class="language-plaintext highlighter-rouge">MaxRAM</code> flag has been marked as deprecated for removal as the JVM can accurately detect physical RAM and set reasonable commit limits. Often times, users were setting other JVM flags: <code class="language-plaintext highlighter-rouge">MaxRAMPercentage</code>, <code class="language-plaintext highlighter-rouge">MinRAMPercentage</code> or <code class="language-plaintext highlighter-rouge">InitialRAMPercentage</code> as a means of getting around <code class="language-plaintext highlighter-rouge">MaxRAM</code>’s default of 128GB. Users should instead use <code class="language-plaintext highlighter-rouge">-Xmx</code> and <code class="language-plaintext highlighter-rouge">-Xms</code> for controlling heap size.</p>

<p><a href="https://bugs.openjdk.org/browse/JDK-8369346">JDK-8369346</a></p>

<h2 id="jmx-updates">JMX Updates</h2>

<p>JMX, Java Management Extensions, is a technology that can be used to provide a view in the a running JVM. There were a number of updates and changes to the JMX API in Java 26.</p>

<h3 id="garbage-collector-cpu-usage">Garbage Collector CPU Usage</h3>

<p>A new method <code class="language-plaintext highlighter-rouge">getTotalGcCpuTime()</code> has been added to <code class="language-plaintext highlighter-rouge">java.lang.management.MemoryMXBean</code>, which returns a long result with the accumulated CPU time in nanoseconds during the critical section and/or after JIT warmup.</p>

<p><a href="https://bugs.openjdk.org/browse/JDK-8368527">JDK-8368527</a></p>

<h3 id="protocal-requires-for-jmxserviceurl">Protocal Requires for JMXServiceURL</h3>

<p>The class <code class="language-plaintext highlighter-rouge">javax.management.remote.JMXServiceURL</code> requires that a protocol is specified when using its String constructor. In prior releases when a <code class="language-plaintext highlighter-rouge">null</code> protocol was supplied to the constructor, the following exception was thrown:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>java.net.MalformedURLException: Unsupported protocol: jmxmp
        at java.management/
        ...
</code></pre></div></div>

<p>This is inaccurate as <code class="language-plaintext highlighter-rouge">jmxmp</code> was a default value, but isn’t part of the JDK. This has been updated to not select <code class="language-plaintext highlighter-rouge">jmxmp</code> and instead print out the follow and more clear message:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>java.net.MalformedURLException: Unsupported protocol: Misssing protocol name
        at java.management/
        ...
</code></pre></div></div>

<p><a href="https://bugs.openjdk.org/browse/JDK-8347114">JDK-8347114</a></p>

<p>The classes <code class="language-plaintext highlighter-rouge">javax.management.AttributeList</code>, <code class="language-plaintext highlighter-rouge">javax.management.relation.RoleList</code>, and <code class="language-plaintext highlighter-rouge">RoleUnresolvedList</code>, have been updated to reject objects of the wrong type, as previous those objects were only verified when the <code class="language-plaintext highlighter-rouge">asList()</code> method was called.</p>

<p><a href="https://bugs.openjdk.org/browse/JDK-8359809">JDK-8359809</a></p>

<h3 id="mbeanserver-exception-change">MBeanServer Exception Change</h3>

<p>The <code class="language-plaintext highlighter-rouge">javax.management.MBeanServer:eregisterMBean()</code> now throws a <code class="language-plaintext highlighter-rouge">RuntimeOperationsException</code> instead of <code class="language-plaintext highlighter-rouge">NullPointerException</code> when invoked with a <code class="language-plaintext highlighter-rouge">null</code> “object” parameter. This correction aligns the implementation with the specification.</p>

<p><a href="https://bugs.openjdk.org/browse/JDK-8364227">JDK-8364227</a></p>

<h2 id="other-changes">Other Changes</h2>

<p>There are a couple of other updates that don’t neatly fit into the above catagories.</p>

<h3 id="c2-jit-support-enhancement">C2 JIT Support Enhancement</h3>

<p>The C2 JIT compiler can now compile Java methods with a large number of parameters (greater than 30). Previously, C2 would bail out when it attempted to compile such methods, causing the JVM to fall back to C1-compiled code or the interpreter.</p>

<p><a href="https://bugs.openjdk.org/browse/JDK-8325467">JDK-8325467</a></p>

<h3 id="serial-gc-eden-space">Serial GC Eden Space</h3>

<p>Prior to Java 26, the ordering of the young generation (YoungGen) in the Serial GC was eden follow by the to/from spaces (survivor regions). This meant that it was difficult for eden to expand to satisfy an allocation request, possibly resulting in a premature <code class="language-plaintext highlighter-rouge">OutOfMemoryException</code> (OOME).</p>

<p>With Java 26, eden has been moved to be after the to/from space, allowing it to possibly grow to the end of YoungGen to satisfy an allocation request. This might mean it grows beyond the limit governed by <code class="language-plaintext highlighter-rouge">SurvivorRatio</code>. However this behavior is desirable as it can avoid an OOME and VM termination.</p>

<p><a href="https://bugs.openjdk.org/browse/JDK-8368740">JDK-8368740</a></p>

<p>Java 26 will be released on March 17th! If you are able to, be sure to attend JavaOne on March 17-19th, in Redwood Shores, California. A large part of the JDK Engineering team will be there, including some of the engineers who worked on the very issues covered in this article. It can be a great opportunity to learn about Java for the stewards of Java! For more check out https://javaone.com, hope you see you there!</p>]]></content><author><name>[&quot;BillyKorando&quot;]</name></author><category term="JDK 26" /><category term="Performance" /><summary type="html"><![CDATA[Let's review the observability and runtime changes coming in Java 26.]]></summary></entry><entry><title type="html">Intelligent JVM Monitoring: Combining JDK Flight Recorder with AI</title><link href="https://inside.java/2026/03/01/jfr-ai-monitor/" rel="alternate" type="text/html" title="Intelligent JVM Monitoring: Combining JDK Flight Recorder with AI" /><published>2026-03-01T00:00:00+00:00</published><updated>2026-03-01T00:00:00+00:00</updated><id>https://inside.java/2026/03/01/jfr-ai-monitor</id><content type="html" xml:base="https://inside.java/2026/03/01/jfr-ai-monitor/"><![CDATA[<div class="youtube-embed">
    <iframe src="https://www.youtube.com/embed/z8mDLU8RCUU" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen=""></iframe>
</div>

<p><em>How do you monitor your JVM applications effectively? One powerful option is JDK Flight Recorder (JFR).</em></p>

<p><em>JFR simplifies troubleshooting and profiling by capturing detailed JVM event data—and with the JFR Streaming API, you can access those insights in real time. But what if you could go further and stream live JFR data straight into an AI system to enhance monitoring, accelerate troubleshooting, and even help prevent issues before they occur?</em></p>

<p><em>In this session, we’ll demonstrate how to use JFR with the latest JDK features to build self-improving applications with the help of AI. Using a real-life simulated example, you’ll learn how to:</em></p>

<ul>
  <li><em>Capture and stream JFR data in real time</em></li>
  <li><em>Integrate JVM event data into an AI-based system</em></li>
  <li><em>Automatically spot performance bottlenecks and unusual behavior</em></li>
  <li><em>Build better tools for debugging and monitoring</em></li>
</ul>

<p><em>By the end of this talk, you’ll have a clear roadmap for combining JFR and AI to improve observability and elevate the troubleshooting experience for your JVM applications.</em></p>

<p>Recorded at <a href="https://www.jfokus.se/">Jfokus 2026</a>.</p>]]></content><author><name>[&quot;YagmurEren&quot;, &quot;JoakimNordstrom&quot;]</name></author><category term="AI" /><category term="JFR" /><category term="Serviceability" /><summary type="html"><![CDATA[JFR simplifies troubleshooting and profiling by capturing detailed JVM event data—and with the JFR Streaming API, you can access those insights in real time. But what if you could go further and stream live JFR data straight into an AI system to enhance monitoring, accelerate troubleshooting, and even help prevent issues before they occur? In this session, we’ll demonstrate how to use JFR with the latest JDK features to build self-improving applications with the help of AI.]]></summary></entry><entry><title type="html">JDK 26 G1/Parallel/Serial GC changes</title><link href="https://inside.java/2026/02/28/jdk26-gc-changes/" rel="alternate" type="text/html" title="JDK 26 G1/Parallel/Serial GC changes" /><published>2026-02-28T00:00:00+00:00</published><updated>2026-02-28T00:00:00+00:00</updated><id>https://inside.java/2026/02/28/jdk26-gc-changes</id><content type="html" xml:base="https://inside.java/2026/02/28/jdk26-gc-changes/"><![CDATA[<p><img class="webfeedsFeaturedVisual" style="display: none;" src="/images/thumbnail/code.jpg" /></p>]]></content><author><name>[&quot;ThomasSchatzl&quot;]</name></author><category term="GC" /><category term="JDK 26" /><summary type="html"><![CDATA[The OpenJDK project is about to release JDK 26 in a few days. This is a good opportunity to add information about notable changes to the stop-the-world collectors in the Hotspot VM.]]></summary></entry><entry><title type="html">Data Oriented Programming, Beyond Records</title><link href="https://inside.java/2026/02/27/beyon-records-dop/" rel="alternate" type="text/html" title="Data Oriented Programming, Beyond Records" /><published>2026-02-27T00:00:00+00:00</published><updated>2026-02-27T00:00:00+00:00</updated><id>https://inside.java/2026/02/27/beyon-records-dop</id><content type="html" xml:base="https://inside.java/2026/02/27/beyon-records-dop/"><![CDATA[<p><img class="webfeedsFeaturedVisual" style="display: none;" src="/images/thumbnail/DukeReadingDocuments.png" /></p>]]></content><author><name>[&quot;BrianGoetz&quot;]</name></author><category term="Amber" /><summary type="html"><![CDATA[We've had some good discussions here, and I've got some updates to the ideas outlined in the previous snapshot. There's a lot here, including a lot that I'm identifying as likely future directions but which should not be the topic of current discussion; I want to focus on the highest-priority aspects first...]]></summary></entry><entry><title type="html">Episode 48 “HTTP/3 in Java 26” [AtA]</title><link href="https://inside.java/2026/02/26/podcast-048/" rel="alternate" type="text/html" title="Episode 48 “HTTP/3 in Java 26” [AtA]" /><published>2026-02-26T00:00:00+00:00</published><updated>2026-02-26T00:00:00+00:00</updated><id>https://inside.java/2026/02/26/Podcast-048</id><content type="html" xml:base="https://inside.java/2026/02/26/podcast-048/"><![CDATA[<p><img class="webfeedsFeaturedVisual" style="display: none;" src="/images/thumbnail/ChadMic.jpg?352445690" /></p>

<p><br /></p>

<iframe title="Libsyn Player" style="border: none" src="//html5-player.libsyn.com/embed/episode/id/40241785/height/90/theme/custom/thumbnail/yes/direction/forward/render-playlist/no/custom-color/000000/" height="90" width="100%" scrolling="no"></iframe>

<div class="youtube-embed">
<iframe src="https://www.youtube.com/embed/Y8ZWHjNP6K4" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen=""></iframe>
</div>

<p><br /></p>

<p>HTTP/3 is the next version of the internet’s most important application layer protocol. But, somewhat surprisingly, it uses UDP (via the new QUIC protocol) instead of TCP/IP, which has implications for the number of initial roundtrips, HTTP version selection, and time to first byte but also adoption and evolution. Java 26 supports HTTP/3 out of the box.</p>

<p>Nicolai Parlog talks to Daniel Fuchs and Daniel Jelinski, both Consulting Members of Technical Staff at Oracle and OpenJDK committers about Java’s HTTP client. They start by briefly retracing its introduction in Java 11 and its support for HTTP/2 before diving deeper into HTTP/3 to learn about the motivation, technical underpinnings like the QUIC protocol, and challengs for its adoption before discussing its integration into Java 26.</p>

<p>(Apologies for the minor audio issues and thank you for your understanding.)</p>

<p>Links:</p>
<ul>
  <li><a href="https://openjdk.org/jeps/517">JEP 517: HTTP/3 for the HTTP Client API</a></li>
  <li><a href="https://inside.java/2025/10/22/http3-support/">Article “HTTP/3 Support in JDK 26”</a></li>
</ul>

<p><br />
Make sure to also check the <strong>Duke’s Corner podcast</strong> on <a href="https://dev.java/duke/corner/">dev.java</a>.</p>

<p><br /></p>

<h3 id="additional-resources">Additional resources</h3>

<ul>
  <li><a href="https://inside.java">Inside.java</a> : News and views from members of the Java team at Oracle</li>
  <li><a href="https://dev.java">Dev.java</a> : The Destination for Java Developers</li>
  <li><a href="https://openjdk.java.net/">OpenJDK</a></li>
  <li><a href="https://www.oracle.com/java/">Oracle Java</a></li>
</ul>

<p>For more episodes, check out <a href="https://inside.java/podcast">Inside Java</a>, our <a href="https://www.youtube.com/playlist?list=PLX8CzqL3ArzV_hXbRevwzrXSMcGNzhxiZ">YouTube playlist</a>, and follow <a href="https://twitter.com/java">@Java</a> on Twitter.</p>

<p>Contact us <a href="https://inside.java/about/">here</a>.</p>]]></content><author><name>[&quot;NicolaiParlog&quot;]</name></author><category term="JDK 26" /><category term="Core Libraries" /><category term="Networking" /><summary type="html"><![CDATA[HTTP/3 is the next version of the internet's most important application layer protocol. In this Inside Java Podcast episode, Nicolai Parlog talks to Daniel Fuchs and Daniel Jelinski about HTTP/3's integration into Java's HTTP client.]]></summary></entry><entry><title type="html">Dissecting the CPU-Memory Relationship in Garbage Collection</title><link href="https://inside.java/2026/02/24/gc-cost-cpu-vs-memory/" rel="alternate" type="text/html" title="Dissecting the CPU-Memory Relationship in Garbage Collection" /><published>2026-02-24T00:00:00+00:00</published><updated>2026-02-24T00:00:00+00:00</updated><id>https://inside.java/2026/02/24/gc-cost-cpu-vs-memory</id><content type="html" xml:base="https://inside.java/2026/02/24/gc-cost-cpu-vs-memory/"><![CDATA[<p><img class="webfeedsFeaturedVisual" style="display: none;" src="/images/thumbnail/code.jpg" /></p>]]></content><author><name>[&quot;JonasNorlinder&quot;]</name></author><category term="JDK 26" /><category term="GC" /><category term="Serviceability" /><summary type="html"><![CDATA[This article analyzes why we need to look beyond GC pauses to enable maximal infrastructure efficiency and introduces the new Java API for GC CPU in OpenJDK 26. These capabilities empower engineers and researchers to quantify the collector's CPU overhead, providing the data necessary to make informed decisions regarding the memory-CPU trade-off.]]></summary></entry></feed>