jvm诸葛老师笔记

本文详细介绍了JVM的工作原理,包括JVM的简单介绍、Math运行过程、栈帧的结构(局部变量表、操作数栈、动态链接、方法出口)以及堆的结构和垃圾收集过程。通过具体的Math函数分析,加深了对栈帧局部变量的理解,并探讨了JVM调优案例。

jvm

jvm简单介绍

在这里插入图片描述
从这张图我们可以清楚的看出来 我们写好的java代码是先经过编译生成class文件
然后才是我们jvm 要做的部分 意思就是java是面向编译之后的class文件产生的 用来屏蔽不同的操作系统在底层和硬件指令上的区别 把class文件翻译成为无论是什么机器都可以 "看懂"的机器码

一个简单的Math运行过程

在这里插入图片描述

public class Math {
    public static final int initDate = 666;
    public User user = new User();

    public Math() {
    }

    public int compute() {
        int a = 1;
        int b = 2;
        int c = (a + b) * 3;
        return c;
    }

    public static void main(String[] args) {
        Math math = new Math();
        math.compute();
    }
}
  1. 就是将class文件加载进类加载子系统
  2. 开辟一个包含 堆,方法区,栈,本地方法栈,程序计数器的空间
  3. 字节码引擎开始执行

课中主要讲解的就是jvm运行空间

栈功能

	栈也叫虚拟机栈,每开辟一个线程就会有一个栈空间被开辟出来 

栈的组成

栈实际上就是栈帧组成的, 而每一个栈帧又存储着与之对应的方法的局部变量表,操作数栈,动态链接,方法出口
也就是一个方法对应一个栈帧 栈帧就是java中每个方法的存放空间
局部变量表 : 存放着方法中的局部变量
操作数栈: 用来操作方法中的数的一个临时栈
动态链接:把符号引用存在直接应用存在内存空间中
方法出口: 记录该方法调用完毕应该回到的地方 (放到我们这个例子中就是回到Main函数的下一行)

下面是Math.java反编译的结果
具体分析compute()函数的指向流程 来深刻的理解帧栈这个空间

Compiled from "Math.java"
public class com.shen.Main.jvm.Math {
  public static final int initDate;

  public com.shen.Main.jvm.User user;

  public com.shen.Main.jvm.Math();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: aload_0
       5: new           #2                  // class com/shen/Main/jvm/User
       8: dup
       9: invokespecial #3                  // Method com/shen/Main/jvm/User."<init>":()V
      12: putfield      #4                  // Field user:Lcom/shen/Main/jvm/User;
      15: return

  public int compute();
    Code:
       0: iconst_1
       1: istore_1
       2: iconst_2
       3: istore_2
       4: iload_1
       5: iload_2
       6: iadd
       7: iconst_3
       8: imul
       9: istore_3
      10: iload_3
      11: ireturn

  public static void main(java.lang.String[]);
    Code:
       0: new           #5                  // class com/shen/Main/jvm/Math
       3: dup
       4: invokespecial #6                  // Method "<init>":()V
       7: astore_1
       8: aload_1
       9: invokevirtual #7                  // Method compute:()I
      12: pop
      13: return
}

栈帧的局部变量其实是用一个数组进行存储的
其中特殊的局部变量0就是this
public int compute();
Code:
0: iconst_1 将局部变量1 放入到操作数栈
1: istore_1 将int类型的值存入局部变量1(将int值赋给在局部变量表的局部变量)
2: iconst_2
3: istore_2
(这就明白了 这两个实际上指行的就是 现在局部变量表中开辟一个b的空间 然后在从操作数栈中弹栈赋给局部变量b)
4: iload_1 //局部变量1压入栈
5: iload_2 //局部变量2 压入栈
6: iadd //弹栈两次 执行int 类型的add
7: iconst_3 //将计算结果 压入栈
8:bipush //将 10压入栈
9: imul //计算乘法结果 在压入栈中
10: istore_3 //将结果存给局部变量3
11: iload_3 //取出局部变量3的值
12: ireturn //return int

局部变量表

存放的就是地址 (如果指向的是对象的话) 也就是math

程序计数器

属于线程私有 用来存放线程执行代码的位置(就是.class文件中的行号) 由字节码执行引擎来操作

方法区

常量 (静态常量)

静态变量(指向堆空间)

方法信息

存放各种new出来的对象
局部变量表会指向
方法区 中的静态变量也会指向

堆结构和垃圾搜集过程在这里插入图片描述

//垃圾搜集都是字节码执行器在做

  1. new 出来的对象都会往 Eden(伊甸)区放 然后满了 会进行minor gc
  2. 存活的放到s0中
  3. 再次满了 再次搜集s0和Eden存活对象 放到s1中
  4. …s1,eden–>s0 不断调换
  5. 年龄到达15的 进入老年区
  6. 老年区满了 会启动full gc 启动full gc时候必须暂停所有执行的代码也就是STW(stop the world) 因为我们的对象必须要有一个确定的状态 不暂停的话就无法确定

一个jvm调优案例

在这里插入图片描述

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值