What is the JRE? Introduction to the Java Runtime Environment
Together, the Java Development Kit (JDK), the Java Virtual Machine (JVM), and the Java Runtime Environment (JRE) form a powerful trifecta of Java platform components for developing and running Java applications. I've previously introduced the JDK and JVM. In this quick tutorial, you'll learn about the JRE, which is the runtime environment for Java.
Practically speaking, a runtime environment is a piece of software that is designed to run other software. As the runtime environment for Java, the JRE contains the Java class libraries, the Java class loader, and the Java Virtual Machine. In this system:
We'll dig a lot deeper into how these components work together in the sections that follow.
From an installation perspective, anytime you download a JDK, it will include a version-compatible JRE, and that JRE will include a default JVM. You also can download the JRE separately from the JDK, and you may choose from a variety of JVMs. Defaults work well for most implementations, especially when you're starting out with Java.
A software program needs to execute, and to do that it needs an environment to run in. The runtime environment loads class files and ensures there is access to memory and other system resources to run them. In the past, most software used the operating system (OS) as its runtime environment. The program ran inside whatever computer it was on, but relied on operating system settings for resource access. Resources in this case would be things like memory and program files and dependencies. The Java Runtime Environment changed all that, at least for Java programs.
When it was first introduced, Java's "write once, run anywhere" principle was considered revolutionary, but today it's been adopted as a norm for most software systems.
We can look at software as a series of layers that sit on top of the system hardware. Each layer provides services that will be used (and required) by the layers above it. The Java Runtime Environment is a software layer that runs on top of a computer's operating system, providing additional services specific to Java.
The JRE smoothes over the diversity of operating systems, ensuring that Java programs can run on virtually any OS without modification. It also provides value-added services. Automatic memory management is one of the JRE's most important services, ensuring that programmers don't have to manually control the allocation and reallocation of memory.
In short, the JRE is a sort of meta-OS for Java programs. It's a classic example of abstraction, abstracting the underlying operating system into a consistent platform for running Java applications.
A Java Virtual Machine is a running software system responsible for executing live Java programs. The JRE is the on-disk system that takes your Java code, combines it with the necessary libraries, and starts the JVM to execute it.
The JRE contains libraries and software that your Java programs need to run. As an example, the Java class loader is part of the Java Runtime Environment. This important piece of software loads compiled Java code into memory and connects the code to the appropriate Java class libraries.
In the layered view I just described, the JVM is created by the JRE. From a package perspective, the JRE contains the JVM, as Figure 1 shows.
Figure 1. A layered architectural view shows that the JRE contains the JVM, class loader, and Java class libraries
While there is a conceptual side to the JRE, in real-world practice it's just software installed on a computer, whose purpose is to run your Java programs. As a developer, you'll mostly work with the JDK and JVM, because those are the platform components you use to develop and run your Java programs. As a Java application user, you would be more involved with the JRE, which lets you run those programs.
In most cases, your computer will come with Java installed, and the JRE will be included with that. If you do ever need to manually install or upgrade, you can download the current JRE version from Oracle.
The Java Runtime Environment is updated for each new version of Java, and its version numbers align with the Java platform versioning system, so for example JRE 1.8 runs Java 8. While you have a variety of JDK packages to choose from (such as Enterprise Edition or Standard Edition) that isn't the case with the JRE. Most computers run a JRE developed for Java SE, which is able to run any Java application regardless of how it was developed. Most mobile devices come with a JRE for Java ME, which is pre-installed on the mobile device and is not available for download.
Once the JRE is installed, you can interact with it on the command-line by entering java -version, which will tell you what version is installed. On POSIX systems, you can always check the installed location with which java.
The JRE is not very noticeable in the development stage, where it mostly just runs your programs in the OS or IDE of your choice. The JRE plays a slightly more prominent role in devops and systems administration because it's used for monitoring and configuration.
Basically, the JRE provides the "knobs" you would use to configure and control the characteristics of a Java application. Memory usage is a prime example, the bread and butter of systems administration. While memory usage is always important, it's vital in cloud configurations, and devops is a cloud-based technology. If you're working in a devops environment, or interested in branching out into devops, it's a good idea to understand how Java memory works and how it's monitored in the JRE.
Devops is a new term, but it describes something that's been true for decades, which is the interoperability between development and operations. In this sense, devops is just a newer term for what used to be called operations or systems administration. Like sysadmin, an important aspect of devops is administering the systems necessary to execute software. Managing the JRE is a part of managing systems that run Java applications.
Java memory consists of three components: the heap, stack and metaspace (which was previously called permgen).
Until Java 8, metaspace was known as permgen. Besides being a much cooler name, metaspace is a significant change to how developers interact with Java's memory space. Previously, you would use the command java -XX:MaxPermSize to monitor the size of permgen space. From Java 8 forward, Java automatically increases the size of the metaspace to accomodate your program's meta-needs. Java 8 also introduced a new flag, MaxMetaspaceSize, which can be used to limit the metaspace size.
The other memory options, heap and stack, remain the same in Java 8.
Heap space is the most dynamic part of the Java memory system. You can use the -Xms and -Xmx flags to tell Java how big to start the heap, and how big to allow it to become. Understanding how to tune these flags for specific program needs is an important aspect of memory management in Java. The ideal is to make the heap big enough to attain the most efficient garbage collection. That is, you want to allow enough memory to let the program run, but you do not want it to be any bigger than necessary.
Stack space is where function calls and variable references are queued. Stack space is the source of the second-most-notorious error in Java programming: the stack overflow exception (the first is the null pointer exception). The stack overflow exception indicates that you've run out of stack space because too much of it has been reserved. Usually, you'll get a stack overflow when a method or methods call each other in a circular fashion, thereby devoting an ever-growing number of function calls into the stack.
You use the -Xss switch to configure the stack starting size. The stack then grows dynamically according to the program's needs.
Although application monitoring is a function of the JVM, the JRE provides configuration options, which are the necessary baseline for monitoring. A variety of tools are available for monitoring Java applications, from the classics (like the Unix command top) to sophisticated remote monitoring solutions like Oracle's infrastructure monitoring.
In between these options are visual profilers like VisualVM that allow for inspecting a running JVM. These tools enable tracking down hotspots and memory leaks, as well as watching overall memory consumption in your system.
The Java Runtime Environment is the on-disk program that loads Java applications for the JVM to execute. A JRE is included by default when you download the Java Development Kit, and each JRE includes the core Java class libraries, a Java class loader, and a Java Virtual Machine. It's helpful to understand how the JVM, JDK and JRE interact, especially for working in cloud and devops environments. In these environments, the JRE takes a stronger role in monitoring and configuration than it would in traditional Java application development.
This story, "What is the JRE? Introduction to the Java Runtime Environment" was originally published by JavaWorld.