By Liang Mao
The extensive ecosystem of Java and its robust and efficient virtual machine technology including memory management (GC) enable the convenient development and versatility of Java applications, significantly reducing the challenges of transitioning ideas into applications. However, this convenience comes with a drawback. The high memory usage of Java applications has been a point of comparison with other languages. While the JVM already includes memory-saving features such as pointer compression (compressed oops), the memory consumption of the Java object header itself remains substantial. This article introduces the latest technology from OpenJDK, compact object headers, which effectively optimizes the memory usage of Java objects. Although this technology has not yet been officially released in the Java language's official implementation, OpenJDK, it has been implemented in Dragonwell 11. For more details, please refer to the JDK release guide: Dragonwell 11 release notes [1].
Compact object headers technology has created the official JEP [2]. The JEP is derived from Lilliput: https://openjdk.org/projects/Lilliput [3] created by the project lead Roman Kenne of the Shenandoah GC.
Object layout of java.lang.long as an example.
The basic idea of compact object headers is to encode a separate narrow klass pointer (compressed class pointer) in the first word: mark word of the object header, freeing up the space of the narrow-klass/klass pointer that originally occupied a word alone, thus achieving an overall memory reduction of java object header. After applying compact object header to java.lang.Long objects, the memory usage is reduced from 24 bytes to 16 bytes, a reduction of 1/3. The original layout of Java object headers needs to support biased locking and CMS GC, and occupy more unused bits. Therefore, compact object header cannot support biased locking and CMS.
(Note: Biased locking is disabled by default in JDK17+, deleted in JDK21+, and CMS GC is deleted in JDK17+)
Early adopters of Project Lilliput who have tried it with real-world applications confirm that live data is typically reduced by 10%–20%
As mentioned in the JEP, 10-20% decreasing is found in memory usage in real-world applications.
An alternative fast locking mechanism is used to replace the original stack locking. The original stack locking requires the object mark word to be exchanged to the stack and results in a remote object header. It’s not safe to get klass pointer with frequent stack lock/unlock.
In Full GC such as G1, the object mark word will be used to save forward oop, so that the class pointer cannot be obtained correctly during GC. Therefore, an additional mechanism is used to save forward oop.
In the G1/Parallel GC process, if there is an evacuation failure, self forwarding will occur. The object header will be used to store its own object pointer (oop), which will also cause the class pointer to be unreadable. Therefore, we need to change the method and use the self forward bit to mark whether the java object (oop) is self forwarded in the GC process.
Implementation of JEP450 compact object headers controlled by +/-UseCompactObjectHeaders.
Fix the potential crash of Arrays.equals on the ARM server due to compact object headers and improve the performance of Arrays.equals on the ARM server.
Dragonwell JDK's UseCompactObjectHeaders completes full JDK regression tests and is used in many core applications of Alibaba. The typical advantages are as follow:
In the SPECjbb2015 benchmark test on the YiTian platform, max(absolute throughput) and critical (low latency required throughput) are improved by 6.17% and 9.01% respectively.
Nexmark, the benchmark test of Flink, shows an average throughput improvement of about 10% on the YiTian platform.
The core applications of Taobao and Tmall e-commerce have G1 young GC frequency decreased by about 7%.
In the Dragonwell 11 JDK versions which support this feature, add the java parameter -XX:+UseCompactObjectHeaders. Note: only -XX:+UseG1GC (default) and -XX:+UseParallelGC are supported.
The current implementation of the compact object headers(JEP450) doesn’t support ZGC, and the implementation detail of JEP450 still needs adjustment to collaborate with ongoing Project Valhalla. Therefore, there is no exact date for the official release of JEP450. However, this does not affect the adaptation of this technology in the current JDK LTS version. Dragonwell 11 only supports the most commonly used G1 GC and Parallel GC with compact object headers. It is currently being used extensively in various scenarios within Alibaba, and no risks have been found so far.
[1] https://github.com/dragonwell-project/dragonwell11/wiki/Alibaba Dragonwell11-Extended release notes
[2] https://openjdk.org/jeps/450
[3] https://openjdk.org/projects/lilliput
[4] https://bugs.openjdk.org/browse/JDK-8291555
[5] https://bugs.openjdk.org/browse/JDK-8305896
[6] https://bugs.openjdk.org/browse/JDK-8305898
[7] https://bugs.openjdk.org/browse/JDK-8305895
[8] https://bugs.openjdk.org/browse/JDK-8328138
Disclaimer: The views expressed herein are for reference only and don't necessarily represent the official views of Alibaba Cloud.
1,076 posts | 263 followers
FollowOpenAnolis - April 22, 2022
OpenAnolis - April 20, 2022
Aliware - April 10, 2020
Alibaba Developer - August 8, 2019
Alibaba Cloud Native Community - March 25, 2019
Alibaba Clouder - October 21, 2020
1,076 posts | 263 followers
FollowExplore Web Hosting solutions that can power your personal website or empower your online business.
Learn MoreA low-code development platform to make work easier
Learn MoreExplore how our Web Hosting solutions help small and medium sized companies power their websites and online businesses.
Learn MoreHelp enterprises build high-quality, stable mobile apps
Learn MoreMore Posts by Alibaba Cloud Community