Java : Evolution of Java Memory Model since Java 8

Hi All,

Today , We will look at how Java Memory Model has evolved with new version of Java after Java 8.

So, Let’s get Started……

What is Java Virtual Machine (JVM):

The Java Virtual Machine (JVM) is a key component of the Java platform that provides hardware and operating system independence, compact compiled code, and protection against malicious programs.

The JVM operates as an abstract computing machine, with its own instruction set and runtime memory management. The use of a virtual machine is a common approach for programming language implementation, with the P-Code machine of UCSD Pascal being a well-known example.

The initial implementation of the JVM was done at Sun Microsystems, Inc. and emulated its instruction set on a handheld device resembling a PDA. Today, Oracle’s implementations run on mobile, desktop, and server devices, but the JVM does not dictate the implementation technology, hardware, or operating system. It can be implemented through software, microcode, or directly on silicon.

The JVM is ignorant of the Java programming language, recognizing only a specific binary format, the class file format. A class file comprises JVM instructions (bytecodes), a symbol table, and other information.

For security reasons, the JVM enforces strict syntax and structural constraints on class files. Nevertheless, any language that can be expressed through a valid class file can run on the JVM, making it an attractive platform for other language implementors.

The JVM described here is compatible with the Java SE 19 platform and supports the Java programming language as defined in The Java Language Specification, Java SE 19 Edition.

Image Credits : https://itzsrv.com/java-memory-model/

The Java Memory Model has undergone several changes since Java 8. Some of the key changes include:

  1. Introduction of Metaspace: In Java 8, the Permanent Generation (PermGen) space was replaced with Metaspace, which is a dynamic memory space for storing class metadata. This eliminated the “java.lang.OutOfMemoryError: PermGen space” error that could occur with PermGen. Details
  2. G1 garbage collector: In Java 9, the G1 garbage collector was introduced as the default garbage collector. It is a low-pause, concurrent garbage collector that is designed to improve the performance of applications with large heap sizes. Details
  3. JDK Flight Recorder (JFR): In Java 9, the JDK Flight Recorder (JFR) was introduced as a commercial feature. JFR is a profiling and event-collection framework that allows developers to collect detailed performance and diagnostic data from a running Java application. Details
  4. Java Improvements for Docker Containers :Java 10 introduced the changes to improve the execution and configurability of Java running in Docker containers.JDK-8146115 Improve docker container detection and resource configuration usage :
    The JVM was modified to be aware that it is running in a Docker container and will extract container specific configuration information instead of querying the operating system. The information being extracted is the number of CPUs and total memory that have been allocated to the container. The total number of CPUs available to the Java process is calculated from any specified cpu sets, cpu shares or cpu quotas. Details
  5. ZGC garbage collector: In Java 11, the ZGC garbage collector was introduced as an experimental feature. It is a low-latency garbage collector that is designed to support large heap sizes with very short GC pauses. Details
  6. Epsilon garbage collector: In Java 11, the Epsilon garbage collector was introduced as an experimental feature. It is a no-op garbage collector that does not perform any actual garbage collection. It is intended for testing and performance evaluation purposes. Details
  7. JEP 331: Low-Overhead Heap Profiling: Java 11 introduced a new feature called Low-overhead Heap Profiling, which allows developers to profile the heap usage of their application with minimal overhead. Details
  8. JEP 379: Shenandoah: A Low-Pause-Time Garbage Collector: Java 12 introduced Shenandoah as a experimental feature, it aims to reduce GC pauses, which can be disruptive in some workloads, by performing more garbage collection concurrently with the running application. Details
  9. JEP 334 JVM Constants API : Java 12 introduced The new package java.lang.invoke.constant introduces an API to model nominal descriptions of class file and run-time artifacts, in particular constants that are loadable from the constant pool. It does so by defining a family of value-based symbolic reference (JVMS 5.1) types, capable of describing each kind of loadable constant. A symbolic reference describes a loadable constant in purely nominal form, separate from class loading or accessibility context. Some classes can act as their own symbolic references (e.g., String); for linkable constants a family of symbolic reference types has been added (ClassDesc, MethodTypeDesc, MethodHandleDesc, and DynamicConstantDesc) that contain the nominal information to describe these constants. Details
  10. JEP 343: Packaging Tool: Java 14 introduced JEP 343, which is a new tool for creating self-contained Java applications. The tool allows developers to package their application and all of its dependencies into a single executable file, making it easier to distribute and run on different systems. Details
  11. JEP 361: Milling Project Coin: Java 14 introduced Milling Project Coin, which is a set of small language changes aimed to improve the readability and expressiveness of the Java language. These changes include the removal of the need for parentheses in some cases when calling methods, the ability to use the var keyword for type inference, and changes to the switch statement to make it more powerful and flexible.Details.
  12. JEP 363: Remove the Concurrent Mark Sweep (CMS) Garbage Collector: Java 14 Removed Concurrent Mark Sweep (CMS) Garbage Collector. Details
  13. JEP 364: ZGC on macOS: Java 14 introduced the ZGC Garbage Collector on macOS, which allows macOS users to benefit from the low-latency and large heap size capabilities of the ZGC GC. Details
  14. JEP 365: ZGC on Windows (Experimental): Java 14 introduced ZGC Garbage Collector on Windows, which allows Windowsusers to benefit from the low-latency and large heap size capabilities of the ZGC GC. Details
  15. JEP 366: Deprecate the ParallelScavenge + SerialOld GC Combination : Java 14 Deprecated the combination of the Parallel Scavenge and Serial Old garbage collection algorithms. This combination must be specifically enabled by the user with the -XX:+UseParallelGC -XX:-UseParallelOldGC command line options. Details
  16. JEP 394: Pattern Matching for instanceof: Java 14 introduced pattern matching for the instanceof operator propsed as JEP-305, which allows developers to match and extract data from objects using a more concise and expressive syntax. This feature is particularly useful for working with complex data structures and for reducing the amount of boilerplate code. Details
  17. JEP 370: Foreign-Memory Access API: Java 14 introduced a Foreign-Memory Access API, which allows Java code to safely and efficiently access foreign memory outside of the Java heap. This feature is particularly useful for memory-intensive applications and for interfacing with other systems and languages. Details
  18. JEP 384: Records: Java 14 introduced Records, which is a new feature that allows developers to define lightweight, immutable, and transparent data classes. Records provide a concise and expressive way to model simple data structures, and are a more concise and readable alternative to traditional Java classes. Details.

19. JEP 371: Hidden Classes: Java 15 introduced the concept of Hidden Classes, which allows to load classes that are not visible to the classloader that loads them, this is a powerful feature for frameworks and libraries that need to load classes dynamically. Details

20.JEP 389: Foreign Linker API: Java 15 introduced a Foreign Linker API, which allows Java code to safely and efficiently link with native libraries and to call native functions. This feature is particularly useful for interfacing with other systems and languages and for performance-critical code.Details

21.JEP 372: Remove the Nashorn JavaScript Engine: Java 15 removed Nashorn JavaScript Engine which was deprecated in Java 11, this engine was used to execute JavaScript code from within Java applications. Details

22.JEP 378: Pattern Matching for instanceof: Java 15 introduced pattern matching for the instanceof operator, which allows developers to match and extract data from objects using a more concise and expressive syntax. This feature is particularly useful for working with complex data structures and for reducing the amount of boilerplate code. Details

23.JEP 373: Reimplement the Legacy DatagramSocket API: Java 15 reimplemented the Legacy DatagramSocket API, which allows developers to work with the DatagramSocket API using the new I/O stack. Details

24.JEP 378: Text Blocks: Java 15 introduced Text Blocks, a new feature that allows developers to define multiline string literals in a more readable and convenient way. This feature is particularly useful for working with large strings, such as JSON or XML data.Details

25.JEP 371: Hidden Classes: Java 15 introduced Hidden classes, which is a new feature that allows developers to load classes that are not visible to the classloader that loads them. Hidden classes are useful for frameworks and libraries that need to load classes dynamically, and can also be used to create more secure and maintainable code by preventing unintended class hierarchies. Details

26.JEP 386: Alpine Linux Port: Java 16 introduced a port of the Java SE Platform to the Alpine Linux operating system, which is a lightweight Linux distribution that is commonly used in container environments. This port allows developers to run Java applications on Alpine Linux with the same features and performance as on other platforms. Details

27.JEP 338: Vector API: Java 16 introduced Vector API, which is a new feature that allows developers to perform vector computations on arrays of primitive values using a set of low-level and highly-optimized instructions. This feature can be used to improve the performance of numerical and scientific computations, and for other types of workloads that can benefit from vectorization.Details

28. JEP 412: Foreign Function & Memory API :
Java 17 introduced a Foreign Function & Memory API by which Java programs can interoperate with code and data outside of the Java runtime. By efficiently invoking foreign functions (i.e., code outside the JVM), and by safely accessing foreign memory (i.e., memory not managed by the JVM), the API enables Java programs to call native libraries and process native data without the brittleness and danger of JNI. Details

29.JEP 400: Sealed Classes: Java 18 introduced Sealed classes, which is a new feature that allows developers to restrict which classes can extend or implement a particular class or interface. This feature can be used to create more secure and maintainable code by preventing unintended class hierarchies. Details

30. JEP 424 Foreign Function & Memory API :Java 19 introduced an API by which Java programs can interoperate with code and data outside of the Java runtime. By efficiently invoking foreign functions (i.e., code outside the JVM), and by safely accessing foreign memory (i.e., memory not managed by the JVM), the API enables Java programs to call native libraries and process native data without the brittleness and danger of JNI. This is a preview API. Details

30-a.JEP 426 Vector API (Fourth Incubator) :Java 19 introduced an API to express vector computations that reliably compile at runtime to optimal vector instructions on supported CPU architectures, thus achieving performance superior to equivalent scalar computations. Details

These are some of the major changes to the Java memory model since Java 8, It’s clear that the JVM team and the Java language designers have been actively working in improving the JVM and the Java language to make it more efficient, expressive, easy to use and powerful for different types of workloads and operating systems.

References:

We hope you liked this post on Evolution Java Memory Model since Java 8 . Overall, the changes to the Java memory model have focused on improving the performance and scalability of the JVM, particularly for applications with large heap sizes and high concurrency.

Happy Learning … Happy Coding …..

Other Interesting Articles:

AWS Lambda in Action

AWS SOAR: Enhancing Security with Automation

Java : Understanding The Golden Ration Phi

AWS Learning : Journey towards Limitless Opportunities in Cloud .

No-cost ways to learn AWS Cloud over the holidays

Understanding 𝗖𝗢𝗥𝗦-𝗖𝗿𝗼𝘀𝘀-𝗢𝗿𝗶𝗴𝗶𝗻 𝗥𝗲𝘀𝗼𝘂𝗿𝗰𝗲 𝗦𝗵𝗮𝗿𝗶𝗻𝗴

Linux Commands for Cloud Learning

Java Programming Principles : Law of Demeter

--

--

Gaurav Rajapurkar - A Technology Enthusiast

An Architect practising Architecture, Design,Coding in Java,JEE,Spring,SpringBoot,Microservices,Apis,Reactive,Oracle,Mongo,GCP,AWS,Kafka,PubSub,DevOps,CI-CD,DSA