Summary of JVM virtual machine knowledge

    • What is a virtual machine?

From a literal point of view, as the name implies, a virtual computer is used to execute virtual computer instructions. In general, virtual machines are generally divided into two types. One is the system virtual machine , and the other is the program virtual machine .

System virtual machine: represented by VMware

Program virtual machine: represented by JVM (java virtual machine)

    • What does the JVM do?

  1. Responsible for loading bytecode into memory (runtime data area)

  1. Convert bytecode to machine code for execution in each system

  1. Responsible for storing data

  1. garbage collection

    • An integral part of the JVM?

  1. class loading

  1. Runtime data area (heap, java virtual machine stack, method area, program counter, local method stack) for details, please click ( java runtime area distribution )

  1. Execution engine (converts bytecode to machine code)

  1. native method interface

  1. garbage collection

The program first converts the java code into a class file (bytecode), and the jvm loads the bytecode into the memory (runtime data area) by means of IO through the class loader, but the bytecode cannot be recognized by the underlying system, so A specific command parser (execution engine) is required to translate the bytecode into the underlying system instructions and hand them over to the CPU for execution. During the execution process, it will call the interface of other languages ​​(local method interface) to realize the function.

    • class loading

    • The role of the class loader?

  1. Responsible for loading section code information from the hard disk|network

  1. Load section code information into memory (runtime data area)

    • class loading process?

    • load
  1. Get the binary byte stream of this class by class name (address)

  1. Convert the static storage structure represented by this byte stream into the running structure of the method area

  1. Generate a java.lang.Class object representing this class in memory as an access interface for various data of this class

    • Link

verify:

Verify the format of the bytecode file, whether the file is polluted

Validate basic syntax

Prepare:

memory allocation for static variables

Static constants are initialized at compile time

Parse:

Convert symbolic references to direct references

Convert bytecode representation to memory representation (memory address)

initialization:

Class initialization, assigning values ​​​​to static variables defined in the class

3. Initialization

Assign values ​​to static variables defined in the class

    • When is the class initialized?

  1. Run the main method in the class

  1. create object

  1. Using static variables and static methods in classes

  1. 反射Class.forNname("类的地址")

  1. 初始化子类的同时也会初始化其父类

注意:以下两种情况不会进行类初始化

先创建两个类

public class User {
    static int a=10;
    static final int b=20;

    static{
        System.out.println(a);
    }
public class TestUser {
    public static void main(String[] args) {

    }
  1. 引用该类的静态常量

public class TestUser {
    public static void main(String[] args) {
  System.out.println(User.b);//调用类中的静态常量不会导致类的加载,有时会在常量在进行计算的情况下才会导致类的加载
    }
  1. 构造某一个类的数组时

public class TestUser {
    public static void main(String[] args) {
    User[] users=new User[10];//构造某个类的数组时不会导致该类的初始化
    }

6.类加载器

  1. 引导类加载器 :用c/c++语言进行开发,java底层的开发语言,负责加载java核心类库

  1. 扩展类加载器 :加载jdk下的 jre/lib/ext 子目录下加载类库

  1. 应用程序类加载器:加载程序中自己开发的类

 ClassLoader classLoader=User.class.getClassLoader();
 ClassLoader classLoader1=classLoader.getParent();
 System.out.println(classLoader);//sun.misc.Launcher$AppClassLoader@18b4aac2  程序类加载器
 System.out.println(classLoader1);//sun.misc.Launcher$ExtClassLoader@1b6d3586  扩展类加载器
 ClassLoader classLoader2=String.class.getClassLoader();
 System.out.println(classLoader2);//null  启动类加载器

双亲委派机制:

我们以String类为例,创建一个java.lang.String的一个类

public class String {
    static{
        System.out.println("自己创建的String类");
    }

    public static void main(String[] args) {
        /*错误: 在类 java.lang.String 中找不到 main 方法, 请将 main 方法定义为:
             public static void main(String[] args)
       否则 JavaFX 应用程序类必须扩展javafx.application.Application*/
    }

我们在类中添加了一个main方法,按道理启动应该是没有什么大问题的,但是当我们运行之后,idea给我们报了一个错,说是在String这个类中找不到main方法,那发生这样的原因是什么呢

原理:当一个类加载器收到类加载请求时,先会委托给父类加载器加载,如果父类加载器还有其父类,则继续向上委托,直到到根加载器(引导类加载器),如果还是找不到,则向下交给子类进行加载,一次类推,直到加载成功或者报错 ClassNotFoundException 异常。

7.本地方法接口

1.什么是本地方法接口?

用native关键字修饰的方法称为一个本地方法,没有方法体,例如:

2.为什么用本地方法?

java语言需要与外部环境进行交互(例如需要访问内存,硬盘,其他的硬件设备),直接访问操作系统的接口即可。

8.执行引擎

1.作用

将加载到内存中的字节码(不能直接运行的机器码),解释/编译为不同平台的机器码。

2.为什么java是半编译半解释型语言?

解释器:将字节码逐行解释执行,效率低

编译器(JIT):将字节码编译,缓存起来,执行更高效,不会立即使用编译器

因为在java程序启动后,先使用解释器立即执行,省去了编译时间,程序运行一段时间后,对热点的编译缓存,提高了后续执行效率,故采用了解释器和编译器结合的方案

Guess you like

Origin blog.csdn.net/dfdbb6b/article/details/128817739