Understanding Java Bytecode, JDK, and JRE

Posted in

Understanding Java Bytecode, JDK, and JRE

Sangeeta Gulia
Last updated on November 10, 2022

    Many processes and threads run parallel when a developer executes a Java program. The architecture behind this execution is complex but understandable when we have deep knowledge of technical terminologies like Bytecode, JVM, JDK, and JRE . The core functionality of JVM is to “Write once, run anywhere”, but understanding how this can be achieved will surely help you to write perfect code.

    In this article, we will try to explain to you the working of JVM, its components, and other features of Java programming execution. If you are working on Java or Scala in your respective organizations, these terms are the basis for the fundamentals of the two languages. The understanding and setup for the above become a prerequisite before you start working on these languages.

    What is Bytecode ?

    It is an intermediate code a compiler generates during the compilation of a code. These are similar to the set of instructions for the compiler to perform some operations converted by JVM into machine code.


    How is the above achieved in a nutshell?

    1. Let’s consider a program. It can be either in java (*.java file) or in scala(*.scala file).
    2. The compiler of the language acts upon the code (javac in the case of java and scalac in the case of scala).
    3. The compiler converts the program into its bytecode (*.class file).
    4. The JVM can understand the bytecode. So, JVM converts it into the machine code (binary format), which the CPU can directly execute.

    What is JVM (Java Virtual Machine)?

    It provides a runtime environment in which bytecode can run. Bytecode and JVM together achieve platform independence. Any programming language whose compiler provides bytecode, as a result, can be run using JVM. Examples of such languages include Java , Scala, etc.

    How does the JVM work?

    JVM consists of the below key units:

    1. Class Loader

    Class loader is the primary unit that starts functioning while doing the below tasks:

    • Loading: It loads the class files into the memory. While an application can have multiple class files, not all class files are loaded into the memory at once but only when the application requires them to be loaded. At this step, JVM distributes the task of loading the class/interface to java.lang.ClassLoader. Loading of classes starts with the call to the main method, and subsequent class loading is done as per the code flow.
    • Linking: During Linking, the semantics of the language are checked. It also validates the data structure as per expectations and throws various errors if it does not match. Once the verification is done, the allocation of resources begins for objects and variables. This is the place where default assignment to variables is done.
    • Initialising: Calling a class or interface's initialization method takes place during the initialization phase. Before initialization, a class or interface must be linked, prepared, and optionally resolved.

    2. JVM memory

    The JVM memory consists of the following areas:

    • Heap Area: Heap area is used to store objects. Its value is configurable using Xms and Xmx fields, where Xms denotes the initial Java heap size and Xmx denotes the maximum Java heap size. A lower Xmx value may lead to reduced performance; hence, frequent garbage collection will be needed to free up the space. If the data size on which the program is operating is larger than the Xmx value, it may lead to an “Out of memory Error”.
    • Class Area(Method Area): This area stores the details of classes, methods, variables, and the constructor details. This area is shared among threads.
    • Stack Area: This area stores the local variables and the return results of the methods. It stores short-lived data. The value of the stack area is also configurable using the Xss field. If the Xss value is insufficient for a program, it results in a StackOverflow Exception.
    • Program Counter Register: It holds the address of the instructions being executed to maintain the flow of the program.
    • Native method Stack: This method holds the details of any technique or library used in the program and is native.

    3. Execution Engine

    The Execution Engine consists of three components, namely an interpreter , JIT compiler , and a garbage collector.

    The execution engine does the actual task of converting the bytecode to machine code. The interpreter reads the code, processes it, and executes it. JIT compiler is used to improve the performance of code. The responsibility of the garbage collector is to free up the space owned by unreferenced objects and methods. The garbage collector is a daemon thread that runs in the background.

    What is JRE (Java Runtime Environment)?

    JRE provides the environment within which JVM can run. JRE is designed for users to run applications that are convertible to bytecode. It can not be used to create new Java programs. In other words, it is a package to run the compiled programs because it consists of JVM, Java Class libraries, java command (java command is used to run any java application), and other infrastructure. JRE is also platform-dependent.

    What is JDK (Java Development Kit)?

    JDK combines JRE and development tools like compilers, debuggers, etc. In addition to JRE, JDK includes a javac compiler used to compile the Java applications, an interpreter, an applet viewer, a document viewer, and other tools, like jar, javadoc (which converts API documentation from Java source code to HTML . It is useful when creating standard documentation in HTML), jshell and jdb. JDK is created for developers to develop applications and programs. JDK is platform-dependent.

    Note: Both JDK and JRE can be used to run java programs.

    Pictorially we can understand the above concepts as below:

    JDK vs JRE vs JVM

    Here are some major differences between JDK vs JRE vs JVM:

    Parameters

    JDK

    JRE

    JVM

    Full Form

    Java Development Kit

    Java Runtime Environment

    Java Virtual Machine

    Definition

    It is a collection of various tools required for developing Java applications. Along with JRE, it contains other development tools, such as a compiler, debugger, etc.

    It is an open-source software distribution consisting of a Java class library, specific tools for running Java applications, and a JVM.

    JVM is an abstract machine that executes Java programs as well as programs written in other languages but compiled into Java bytecode.

    Platform Independent

    No

    Yes

    Yes

    Tools

    Includes tools for developing, debugging, and monitoring Java applications.

    Contains Java class libraries and other files required for JVM to run Java programs

    Does not include any software development tool.

    Implementation

    JDK = JRE+JVM

    JRE = JDK + Java class library

    JVM = a simple machine for running Java bytecode.

    Conclusion

    With this small write-up, we understood the program's environment. After gathering this information, we can write our programs more effectively, where we can picturize our program in terms of JVM and the runtime environment. In future blogs, we will understand the languages in more detail which are compatible with JVM.

    Please leave us feedback if you like this article and found it helpful!

    Happy learning!

    People are also reading:

    Tags:
    java

    FAQs


    JDK is a Java Development Kit that contains essential tools for developing Java applications. On the other hand, JRE is a short form for Java Runtime Environment, which executes Java programs.

    Yes, JDK includes JRE, along with all other development tools required for developing Java applications.

    Bytecode is an intermediate code or intermediate representation of a Java program. JVM takes bytecode and converts it into machine code.

    No, you cannot run a Java program without installing JDK because it contains all the essential development binaries required for the execution of Java programs.

    JVM has both an interpreter and a compiler. Initially, a compiler converts a Java program into bytecode, and later, an interpreter bytecode into machine code.

    Leave a Comment on this Post

    0 Comments