JVM 一 (JVM的整体结构)


#JVM 中的位置
在这里插入图片描述
JVM是运行在操作系统之上的,他与硬件没有直接的交互。
不同的操作系统装的JVM是有区别的。

JVM的整体结构

在这里插入图片描述
JVM是解释运行字节码(.class)文件的。
类加载器子系统:字节码文件需要使用类加载器子系统加载到内存当中,生成一个大的class对象。(过程涉及到加载、链接、初始化)
类加载子系统,加载字节码之后会在方法区生成class实例
方法区、堆:多线程共享堆和方法区
栈(虚拟机栈)、本地方法栈、程序计数器:每个线程独有一份的。
执行引擎:解释器、即时编译器(JIT)、GC。对于反复执行的代码希望能够提前编译出来。就会使用JIT。
执行引擎主要作用:操作系统只能识别机器指令,字节码指令是不同于机器指令的,要想字节码能够解释执行就需要借助执行引擎。执行引擎就充当的把高级语言翻译成机器语言。

Java代码的执行流程

在这里插入图片描述
java源文件通过编译生成字节码文件、字节码文件进行解释执行。
在这里插入图片描述

在这里插入图片描述
JIT编译器,保证了程序的性能,它会把一些热点代码缓存到本地。

JVM的架构模型

JVM 是基于栈的指令集架构
在这里插入图片描述

创建一个简单的类

package com.atguigu.java;

public class StackruTest {
    public static void main(String[] args) {
        int a=1+2;
    }
}

使用javap -v StackruTest.class 反编译字节码文件


Classfile /D:/WljFile/YCSun/JVMDemo/chapter01/target/classes/com/atguigu/java/StackruTest.class
  Last modified 2022-5-25; size 434 bytes
  MD5 checksum 8a8df5dd8122e079ff5fc438f8a1fcef
  Compiled from "StackruTest.java"
public class com.atguigu.java.StackruTest
  minor version: 0
  major version: 49
  flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
   #1 = Methodref          #3.#19         // java/lang/Object."<init>":()V
   #2 = Class              #20            // com/atguigu/java/StackruTest
   #3 = Class              #21            // java/lang/Object
   #4 = Utf8               <init>
   #5 = Utf8               ()V
   #6 = Utf8               Code
   #7 = Utf8               LineNumberTable
   #8 = Utf8               LocalVariableTable
   #9 = Utf8               this
  #10 = Utf8               Lcom/atguigu/java/StackruTest;
  #11 = Utf8               main
  #12 = Utf8               ([Ljava/lang/String;)V
  #13 = Utf8               args
  #14 = Utf8               [Ljava/lang/String;
  #15 = Utf8               a
  #16 = Utf8               I
  #17 = Utf8               SourceFile
  #18 = Utf8               StackruTest.java
  #19 = NameAndType        #4:#5          // "<init>":()V
  #20 = Utf8               com/atguigu/java/StackruTest
  #21 = Utf8               java/lang/Object
{
  public com.atguigu.java.StackruTest();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: invokespecial #1                  // Method java/lang/Object."<init>":()V
         4: return
      LineNumberTable:
        line 3: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       5     0  this   Lcom/atguigu/java/StackruTest;

  public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=1, locals=2, args_size=1
         0: iconst_3
         1: istore_1
         2: return
      LineNumberTable:
        line 5: 0
        line 6: 2
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       3     0  args   [Ljava/lang/String;
            2       1     1     a   I
}

```xml
public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=1, locals=2, args_size=1
         0: iconst_3 //初始化一个3
         1: istore_1 保存起来   1是 操作数栈中的索引位置
         2: return
      LineNumberTable:
        line 5: 0
        line 6: 2
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       3     0  args   [Ljava/lang/String;
            2       1     1     a   I
 Code: 是方法的指令内容
 

重新把main方法写的复杂一些


public class StackruTest {
    public static void main(String[] args) {
        int a= 2;
        int b= 3;
        int c=a+b;
    }
}

重新反编译字节码

public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=4, args_size=1
         0: iconst_2 初始化 2
         1: istore_1 保存
         2: iconst_3 初始化3
         3: istore_2 保存
         4: iload_1  加载1(猜测istore_1)
         5: iload_2  加载2  (猜测istore_2)
         6: iadd  进行相加计算
         7: istore_3 (计算的结果保存3)
         8: return
      LineNumberTable:
        line 5: 0
        line 6: 2
        line 7: 4
        line 8: 8
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       9     0  args   [Ljava/lang/String;
            2       7     1     a   I
            4       5     2     b   I
            8       1     3     c   I
}

其他例子

在这里插入图片描述

在这里插入图片描述

Code:

JVM的生命周期

JVM的启动

java虚拟机的启动是通过引导类加载器(bootstrap class loader )创建一个初始类(initial class)来完成的,这个类是有虚拟机的具体实现指定的。
加载去分为: 引导类加载器、扩展类加载器、系统类加载器

在代码中自己定义的类需要加载是通过系统类加载器(或者应用类加载器)来实现的,定义的类没有默认是继承Object 的,Object 作为核心API是需要引导类进行加载的。
父类的加载是早于子类的

JVM的执行

  • 一个运行的java虚拟机有着一个清晰的任务:执行java程序
  • 程序开始执行时它才会运行,程序结束时它就会停止
  • 执行一个所谓的java程序的时候,真真正正在执行的是一个叫做java虚拟机的进程

查看JVM进程

public class StackruTest {
    public static void main(String[] args) {
        int a= 2;
        int b= 3;
        int c=a+b;
        try {
            //睡一会
            Thread.sleep(8000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

使用jps 查看 查看程序执行的进程

D:\WljFile\YCSun\JVMDemo\chapter01\target\classes\com\atguigu\java>jps
18516 OracleIdeLauncher
28792 Launcher
29256 StackruTest 程序执行的进程 PID 29256
2284 Jps
29404 RemoteMavenServer36
3932


线程结束 没有运行的线程 再次使用jps 查看进程


D:\WljFile\YCSun\JVMDemo\chapter01\target\classes\com\atguigu\java>jps
18516 OracleIdeLauncher
23156 Jps
22056 Launcher
29404 RemoteMavenServer36
3932

JVM的退出

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值