- Java Runtime Environment Tutorial
- 1. What is a runtime environment?
- 2. Pre-requisites
- 3. Installing and using the JRE
- 3.1 Set up environment
- 3.2 Set up with JDK
- 3.3 Running a Java class
- 4. Java memory and the JRE
- 4.1 Memory management
- 4.2 Heap space
- 4.3 Stack space
- 4.4 Application monitoring
- 5. Summary
- 6. More articles
- 7. Download the Source Code
- Program: How to get process environment variables in java at runtime?
- List Of All ProcessBuilder Class Sample Programs:
- About Author
- Most Visited Pages
Java Runtime Environment Tutorial
In this article, we’re going to discuss Java Runtime Environment, the bundle used to run Java applications and libraries.
1. What is a runtime environment?
The runtime environment is the environment in which a program or application is executed. As soon as a software program is executed, it is in a runtime state. Java Runtime Environment (JRE) is the software bundle to execute the Java class libraries. This bundle is a bit different from Java Development Kit (JDK), due to it has only the necessary libraries and the Java Virtual Machine (JVM) to execute the Java-based application. As the runtime environment is just to execute the software, it won’t have some development tools for debugging and compiling. The first thing we can ask is why not use the JDK already? That’s because, in a production environment, it’s not a good deal to have tools that can expose the application’s source code. So, using a runtime environment is the best option to execute our application and also use just the necessary to take advantage of available resources. In the next sessions, we’re going to see how to set up and use the JRE and some features present in this environment.
2. Pre-requisites
The JDK already brings the JRE embedded. However, for this article, we’ll use Java SE Runtime Environment 8u281 due to licensing reasons. This version is the last free JRE found today. Download the compatible version for your OS here. I recommend downloading the compressed file, as we’re going to take some work to use together with JDK, if necessary. The minimum Java version for executing the article’s example is JDK 8 (find here), but we can use the most recently released Java version JDK 16 on Oracle’s official site or the OpenJDK version.
Also, I’m using the most recent IntelliJ version, but you can use any IDE with support for the versions recommended above.
3. Installing and using the JRE
After downloading the JRE package, if you have a JDK configured in your machine, you can walk through item 3.2. The first move is to extract the compressed package (if you downloaded it) in a proper directory.
3.1 Set up environment
When using a Linux or macOS system, we can use the terminal to set up environment variables. Here we’ll define the JAVA_HOME variable to use in our OS. Setup Linux/MacOS variable
// Linux $ export JAVA_HOME=/your_jre_extracted_folder/jre1.8.0_281.jre/ // MacOS $ export JAVA_HOME=/your_jre_extracted_folder/jre1.8.0_281.jre/Contents/Home
On Windows, you go to your Control Panel > System > Advanced system settings > Environment Variables and set the JAVA_HOME variable.
To test the installation, just run the command below to check the version available. Works for all OS. Check installation
$ java -version java version "1.8.0_281" Java(TM) SE Runtime Environment (build 1.8.0_281-b09) Java HotSpot(TM) 64-Bit Server VM (build 25.281-b09, mixed mode)
3.2 Set up with JDK
To use the JRE together with our JDK, we need to do a little trick. Instead of using the traditional JAVA_HOME variable, we’ll use another variable that indicates the JRE location. For that, I name the variable JRE_HOME. Setup Linux/MacOS JRE_HOME variable
// Linux $ export JRE_HOME=/you_jre_extracted_folder/jre1.8.0_281.jre/ // MacOS $ export JRE_HOME=/you_jre_extracted_folder/jre1.8.0_281.jre/Contents/Home
Linux and macOS have a feature called that makes our life easier. With this command, we can create a shortcut to call the java executor from our JRE_HOME. Using alias command Linux/MacOS
$ alias jre8=$JRE_HOME/bin/java
$ jre8 -version java version "1.8.0_281" Java(TM) SE Runtime Environment (build 1.8.0_281-b09) Java HotSpot(TM) 64-Bit Server VM (build 25.281-b09, mixed mode)
Almost the same on Windows, but a bit different. We are going to create the JRE_HOME variable as well, but we’ll create a “kind of” alias when creating another variable called jre8 pointing to the previous JRE_HOME. The place to create the environment variable is the same Control Panel > System > Advanced system settings > Environment Variables.
> %jre8% -version java version "1.8.0_281" Java(TM) SE Runtime Environment (build 1.8.0_281-b09) Java HotSpot(TM) 64-Bit Server VM (build 25.281-b09, mixed mode)
3.3 Running a Java class
To execute a Java class, we’ll need a .class file already compiled. I put a simple class called TestMain on the source code of this article, and you can run it with the command below: Running Java class
// with JAVA_HOME (any OS) $ java TestMain Hello World! // with JRE_HOME (Linux/MacOS) $ jre8 TestMain Hello World! // with JRE_HOME (Windows) > %jre8% TestMain
4. Java memory and the JRE
When we talk about the production environment, memory management is a great challenge. JRE has some features that help us on that mission using a few command lines to do it.
4.1 Memory management
More information and details can be read here. In the next sections, we’ll see the aspects of heap and stack space.
4.2 Heap space
The heap space in Java is the dynamic memory allocation for objects and classes at runtime. To clarify is where the JVM loads the application’s byte codes.
The memory is used as long as the application is running. When an object is created, it is always created in Heap and has global access. That means all objects can be referenced from anywhere in the application.
- Young generation – this is where all new objects are allocated and aged. A minor Garbage collection occurs when this fills up.
- Old or Tenured Generation – this is where long surviving objects are stored. When objects are stored in the Young Generation, a threshold for the object’s age is set and when that threshold is reached, the object is moved to the old generation.
- Permanent Generation – this consists of JVM metadata for the runtime classes and application methods.
- -Xms : To set an initial java heap size
- -Xmx : To set maximum java heap size
- -Xss : To set the Java thread stack size
- -Xmn : For setting the size of young generation, rest of the space goes for old generation
In the example below, we’re setting 100 megabytes (m) as the maximum to our application running. Setting heap size
// with JAVA_HOME (any OS) $ java -Xmx100m TestMain Hello World! // with JRE_HOME (Linux/MacOS) $ jre8 -Xmx100m TestMain Hello World! // with JRE_HOME (Windows) > %jre8% -Xmx100m TestMain
We can also set a start memory and limit the heap. Setting heap size start and maximum
// with JAVA_HOME (any OS) $ java -Xms512m -Xmx1024m TestMain Hello World! // with JRE_HOME (Linux/MacOS) $ jre8 -Xms512m -Xmx1024m TestMain Hello World! // with JRE_HOME (Windows) > %jre8% -Xms512m -Xmx1024m TestMain
4.3 Stack space
The stack space is the temporary memory where variable values are stored when their methods are invoked. When the method ends, that block will be erased. The next method invoked will use that empty block.
This concept is called Last-In-First-Out (LIFO), which means whenever a new method is called, it’ll be inserted on the top of the stack to the application access.
Using the -Xss option we can set our stack on Java application. In the next example, we’re setting 512 kilobytes (k): Setting heap size start and maximum
// with JAVA_HOME (any OS) $ java -Xss512k TestMain Hello World! // with JRE_HOME (Linux/MacOS) $ jre8 -Xss512k TestMain Hello World! // with JRE_HOME (Windows) > %jre8% -Xss512k TestMain
4.4 Application monitoring
As JRE is a bundle to only run Java applications, some tools as monitoring aren’t included. However, we can use some JVM options to do a kind of monitoring in our Java applications.
The command below helps to see the allocation of heap space. Dumping heap space
// with JAVA_HOME (any OS) $ java -Xloggc:output.log -XX:+PrintGCDetails -Xms256m -Xmx512m TestMain // with JRE_HOME (Linux/MacOS) $ jre8 -Xloggc:output.log -XX:+PrintGCDetails -Xms256m -Xmx512m TestMain // with JRE_HOME (Windows) > %jre8% -Xloggc:output.log -XX:+PrintGCDetails -Xms256m -Xmx512m TestMain
The command writes the output with the option -Xloggc:output.log. In this file, we will see how JVM manages the initial ( -XX:InitialHeapSize ) and maximum ( -XX:MaxHeapSize ) memory allocation. Also, we see some information about Garbage Collection dealing with heap space. output
Java HotSpot(TM) 64-Bit Server VM (25.281-b09) for bsd-amd64 JRE (1.8.0_281-b09), built on Dec 9 2020 12:44:49 by "java_re" with gcc 4.2.1 Compatible Apple LLVM 10.0.0 (clang-1000.11.45.5) Memory: 4k page, physical 8388608k(33900k free) /proc/meminfo: CommandLine flags: -XX:InitialHeapSize=268435456 -XX:MaxHeapSize=536870912 -XX:+PrintGC -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseParallelGC Heap PSYoungGen total 76288K, used 3932K [0x00000007b5580000, 0x00000007baa80000, 0x00000007c0000000) eden space 65536K, 6% used [0x00000007b5580000,0x00000007b5957240,0x00000007b9580000) from space 10752K, 0% used [0x00000007ba000000,0x00000007ba000000,0x00000007baa80000) to space 10752K, 0% used [0x00000007b9580000,0x00000007b9580000,0x00000007ba000000) ParOldGen total 175104K, used 0K [0x00000007a0000000, 0x00000007aab00000, 0x00000007b5580000) object space 175104K, 0% used [0x00000007a0000000,0x00000007a0000000,0x00000007aab00000) Metaspace used 2511K, capacity 4486K, committed 4864K, reserved 1056768K class space used 267K, capacity 386K, committed 512K, reserved 1048576K
More options can be explored here in Oracle’s JVM HotSpot Debugging.
Note: the command above is deprecated since Java 9. An alternative way is using the -Xlog:gc option from Java 9 and newer versions.
5. Summary
In summary, we’ve seen the differences between the JRE bundle and JDK. Further, we could install and set up the standalone JRE, and change some settings to use it instead of JDK.
Also, we could check how memory management works using some command option lines introduced in JRE to handle JVM memory use and do a kind of monitoring too.
6. More articles
7. Download the Source Code
Download
You can download the full source code of this example here: Java Runtime Environment Tutorial
Last updated on Jan. 13th, 2021
Program: How to get process environment variables in java at runtime?
The ProcessBuilder.environment() method returns you the ProcessBuilder’s environemnt. Below example shows how to read it.
package com.java2novice.processbuilder; import java.util.Map; import java.util.Set; public class MyEnvDetails < public static void main(String a[])< ProcessBuilder pb = new ProcessBuilder(); MapenvMap = pb.environment(); Set keys = envMap.keySet(); for(String key:keys) < System.out.println(key+" ==>"+envMap.get(key)); > > >
SHELL ==> /bin/bash JAVA_MAIN_CLASS_37131 ==> com.java2novice.processbuilder.MyEnvDetails APP_ICON_385 ==> ../Resources/Eclipse.icns com.apple.java.jvmMode ==> client TMPDIR ==> /var/folders/2n/yf7x2fdx3bv6g31hn4stv1y0_qsrzm/T/ __CF_USER_TEXT_ENCODING ==> 0x157CE3F4:0:0 PATH ==> /usr/bin:/bin:/usr/sbin:/sbin COMMAND_MODE ==> unix2003 DISPLAY ==> /tmp/launch-DwnV41/org.x:0 USER ==> root com.apple.java.jvmTask ==> JNI.java JAVA_STARTED_ON_FIRST_THREAD_385 ==> 1 Apple_Ubiquity_Message ==> /tmp/launch-u3pr6e/Apple_Ubiquity_Message LOGNAME ==> root Apple_PubSub_Socket_Render ==> /tmp/launch-nboOhX/Render
List Of All ProcessBuilder Class Sample Programs:
Transient: The transient modifier applies to variables only and it is not stored as part of its object’s Persistent state. Transient variables are not serialized.
Volatile: Volatile modifier applies to variables only and it tells the compiler that the variable modified by volatile can be changed unexpectedly by other parts of the program.
About Author
I’m Nataraja Gootooru, programmer by profession and passionate about technologies. All examples given here are as simple as possible to help beginners. The source code is compiled and tested in my dev environment.
If you come across any mistakes or bugs, please email me to [email protected] .