深入理解JVM:jvm的体系结构及运行过程

jdk、jre、jvm

在这里插入图片描述
jdk中的文件

bin:最主要的是编译器javac.exe
include:java和jvm交互的头文件
lib:类库
jre:java运行环境

金字塔结构 JDK=JRE+JVM+其它 运行Java程序一般都要求用户的电脑安装JRE环境(Java Runtime Environment);没有jre,java程序无法运行;而没有java程序,jre就没有用武之地。

HotSpot虚拟机

包括两种:Client VM 和 Server VM

Client VM(-client),为在客户端环境中减少启动时间而优化;
Server VM(-server),为在服务器环境中最大化程序执行速度而设计。

比较:Server VM启动比Client VM慢,运行比Client VM快。

配置文件的位置如下:

若为64位操作系统
	{JRE_HOME}/lib/amd64/jvm.cfg
若为32位操作系统
	{JRE_HOME}/lib/i386/jvm.cfg

配置文件里面第一行写的是 -client 默认就是client版本,把第二行的-server KNOWN 放到第一行,就会变成sercer版本,如下面所示:
在这里插入图片描述

也可以在控制命令台搜java -version,查看虚拟机类型
在这里插入图片描述

java是如何实现跨平台的?

“一次编译,到处运行”

不同的操作系统,底层的指令是不同的,底层的指令只能识别机器码(01001011)

java虚拟机从软件层面屏蔽了底层硬件指令层面的细节

在这里插入图片描述
Java之所以可以做到跨平台,是因为Java虚拟机充当了桥梁。他扮演了运行时Java程序与其下的硬件和操作系统之间的缓冲角色。
在这里插入图片描述
问题:C/C++可以跨平台吗?
C/C++是编译时跨屏台,Java是运行时跨平台。

jvm体系结构

在这里插入图片描述

首先通过类加载器(ClassLoader)会把编译后的字节码文件加载入内存中,

运行时数据区(Runtime Data Area)再把字节码加载到内存中,而字节码文件只是 JVM 的一套指令集规范,并不能直接交个底层操作系统去执行,

因此需要特定的命令解析器执行引擎(Execution Engine),将字节码翻译成底层系统指令,再交由 CPU 去执行,

而这个过程中需要调用其他语言的本地库接口(Native Interface)来实现整个程序的功能。

栈的先进后出原则

堆——存放对象,线程共享;

栈——执行程序,线程私有;

一个方法一个栈帧
在这里插入图片描述

底层的运行过程

HelloWorld.java

package example;

/**
 * @Author:liujiamei
 * @Date:2020/5/28 8:16
 * @Version 1.0
 */
public class HelloWorld {

    public static void main(String[] argv) {

        HelloWorld hw = new HelloWorld();
        int result = hw.add();
        System.out.println(result);

    }

    /**
     * 计算方法,局部变量
     * 一个方法为一个栈帧:以方法进行数据隔离
     * @return
     */
    public int add() {
        int a, b, c;//存储在add方法的局部变量表中
        a = 1;
        b = 2;
        c = a + b;
        return c;
    }
}

HelloWorld.class字节码文件
在这里插入图片描述
javap代码反汇编

javap
javap -c HelloWorld.class
>javap -c HelloWorld.class>hw.txt

在这里插入图片描述

hw.txt

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

  public static void main(java.lang.String[]);
    Code:
       0: new           #2                  // class example/HelloWorld
       3: dup
       4: invokespecial #3                  // Method "<init>":()V
       7: astore_1
       8: aload_1
       9: invokevirtual #4                  // Method add:()I
      12: istore_2
      13: getstatic     #5                  // Field java/lang/System.out:Ljava/io/PrintStream;
      16: iload_2
      17: invokevirtual #6                  // Method java/io/PrintStream.println:(I)V
      20: return

  public int add();
    Code:				//线程的程序计数器:指向当前字节码指令的(地址)行号
       0: iconst_1		//将int类型常量1压入栈,将1放入操作数栈
       1: istore_1		//将int类型值存入局部变量1,a=1
       2: iconst_2
       3: istore_2
       4: iload_1		//从局部变量1装载int类型值,再压入操作数栈
       5: iload_2
       6: iadd			//执行int类型的加法,1和2出栈,1+2=3,
       7: istore_3		//3压入操作数栈,此时操作数栈只有3
       8: iload_3
       9: ireturn		//从方法中返回int类型的数据,通过方法出口返回给main方法
}

jvm指令集代码 https://blog.csdn.net/zhangpan19910604/article/details/52254053
在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值