Java Virtual Machine (JVM) - Bytecode

1. What is bytecode?

1. Bytecode overview

        Java bytecode is the instruction set of the Java Virtual Machine. It acts like an assembler, which is an alias for C++ code. Once a java program is compiled, java bytecode is generated. In more appropriate terms, java bytecode is machine code in the form of a .class file. We have achieved platform independence in java with the help of java bytecode.

2. Bytecode and Assembly Language

        Bytecode is similar to assembly language in that it is not a high-level language, but unlike machine language, it is still somewhat readable. Both can be thought of as an "intermediate language" between source code and machine code. The main difference between the two is that bytecode is generated for a virtual machine (software) whereas assembly language is generated for a CPU (hardware).

2. How does it work?

        When we write a program in Java, first, the compiler compiles the program and generates a bytecode for the code. We can do this when we want to run this .class file on any other platform. After the first compilation, the resulting bytecode is now run by the Java virtual machine instead of the processor in question. This essentially means that we just need to install basic java on whatever platform we want to run the code on. The resources required to run the bytecode are provided by the Java virtual machine, which calls the processor to allocate the required resources. JVMs are stack based, so they stack implementations to read code.

Third, the advantages of Java bytecode

        Platform independence is one of the important features that James Gosling gave to java, and it is the implementation of this bytecode that helps us achieve this. Therefore, bytecode is a very important part of any java program. The instruction set of the JVM may vary from system to system, but all can interpret bytecode. One thing to remember is that bytecode is non-runnable code and relies on the availability of an interpreter to execute, so the JVM comes into play.

        Bytecode is essentially a machine-level language that runs on the Java Virtual Machine. Whenever a class is loaded, it gets a stream of bytecodes for each method of that class. Whenever the method is called during program execution, the method's bytecode is called. Javac not only compiles programs, but also generates bytecode for programs. Therefore, we have realized that the implementation of bytecode makes Java a platform independent language. This helps to add portability to Java that languages ​​such as C or C++ lack. Portability ensures that Java can be implemented on various platforms such as desktop, mobile, server, etc. To support this, Sun Microsystems named JAVA "write once, read anywhere" or "WORA" to resonate with bytecode interpretation.

Fourth, how to view the bytecode

        View through javac and javap: first compile the .java file into a .class bytecode file through javac, and then analyze the bytecode through javap -verbose.

1. javap command description

  -help --help -? print this usage message
  -version version info
  -v -verbose print additional info
  -l print line numbers and local variable table
  -public only show public classes and members
  -protected show protected/public classes and members
  -package show package/protected/public classes and members (default)
  -p -private show all classes and members
  -c disassemble code
  -s output internal type signatures
  -sysinfo show system information for classes being processed ( path, size, date, MD5 hash)
  -constants show final constants
  -classpath <path> specify where to find user class files
  -cp <path> specify where to find user class files
  -bootclasspath <path> override where boot class files are located

2. Output additional information

javap -verbose Base

        The output is as follows

Classfile /C:/Program Files/Java/jdk1.8.0_91/bin/Base.class
  Last modified 2022-3-6; size 218 bytes
  MD5 checksum 9a79a6c59f787265dae97730351d7e23
  Compiled from "Base.java"
abstract class Base
  minor version: 0
  major version: 52
  flags: ACC_SUPER, ACC_ABSTRACT
Constant pool:
   #1 = Methodref          #3.#12         // java/lang/Object."<init>":()V
   #2 = Class              #13            // Base
   #3 = Class              #14            // java/lang/Object
   #4 = Utf8               <init>
   #5 = Utf8               ()V
   #6 = Utf8               Code
   #7 = Utf8               LineNumberTable
   #8 = Utf8               method1
   #9 = Utf8               method2
  #10 = Utf8               SourceFile
  #11 = Utf8               Base.java
  #12 = NameAndType        #4:#5          // "<init>":()V
  #13 = Utf8               Base
  #14 = Utf8               java/lang/Object
{
  Base();
    descriptor: ()V
    flags:
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: invokespecial #1                  // Method java/lang/Object."<init>":()V
         4: return
      LineNumberTable:
        line 1: 0

  public abstract void method1();
    descriptor: ()V
    flags: ACC_PUBLIC, ACC_ABSTRACT

  public abstract void method2();
    descriptor: ()V
    flags: ACC_PUBLIC, ACC_ABSTRACT
}
SourceFile: "Base.java"

3. Decompile the code

javap -c Base.class

        The output is as follows

​Compiled from "Base.java"
abstract class Base {
  Base();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public abstract void method1();

  public abstract void method2();
}

4. Idea configuration macro

Idea2017 View Class Bytecode File This tool can view the compiled class file of java. Use the following command to view: javap -c Student where Student is the Student.class file -c: option to view the disassembly code of the code 2. Configure macros under Idea2017 First enter Idea and open File->Settings. Select https://blog.csdn.net/kingolie/article/details/79324138

Five, virtual machine bytecode instruction set

        The image below is a partial example. See Java Virtual Machine Instruction Set for details

Chapter 6. The Java Virtual Machine Instruction Sethttps://docs.oracle.com/javase/specs/jvms/se12/html/jvms-6.html#jvms-6.5.nop

6. Simple example

1. Class code

package com.algorithm.demo.algorithms;

public class ByteCodeTest{

    public static void InitAndAdd()
    {
        int i=99;
        i++;
    }

}

2. Bytecode

Compiled from "ByteCodeTest.java"
public class com.algorithm.demo.algorithms.ByteCodeTest {
  public com.algorithm.demo.algorithms.ByteCodeTest();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public static void InitAndAdd();
    Code:
       0: bipush        99
       2: istore_0
       3: iinc          0, 1
       6: return
}

        Let's focus on the InitAndAdd method.

        1. int i=99; corresponds to the following two steps

0: bipush 99 //Push a byte into the operand stack (its length will be filled with 4 bytes)

2: istore_0 //Store the int into a local variable

        2. i++; corresponds to the following two steps

       3: iinc 0, 1 //increment local variable
       6: return //return

Guess you like

Origin blog.csdn.net/bashendixie5/article/details/123221228