JVM(一)入门以及Class文件格式

虚拟机概念

Jvm从编码到执行

  1. Jvm是怎么样从编码到执行的整个的过程到底什么是JVM
  • 执行过程

我们有一个文件x.java->执行javac->变成x.class,当我们调用java命令的时候class会被装载到内存叫classLoader.

一般的情况下我们写自己类文件的时候也会用到java的类亏,所以它要把java类库相关类也装载到内存里,装载完成之后会调用字节码解释器或者是即使编译器来进行解释或编译,编译完之后由执行引擎开始执行,执行引擎下面面对就是操作系统的硬件了,这块的内容叫jvm.

  • Java是解释执行还是编译执行?

其实解释和编译是可以混合执行的,特别常用的一些代码,用到的次数非常多,这时候他会把一个即使编译器做成一个本地的编译,就像c语言在window上执行的时候把它编译成exe一样,那么下次在执行这段代码的时候就不需要解释器来一句一句的解释来执行,执行引擎可以直接交给操作系统去让他调用,这个效率会高很多,不是所以的代码都会被JIT进行即时编译的.这一块叫java虚拟机

在这里插入图片描述

  • 什么是JVM
    JVM现在我们可以称之为它是一个跨语言的平台,java叫跨平台的语言,作为jvm虚拟机来讲目前能够在jvm上跑的语言特别多,除java以外,还有scala,kotlin,groovy等等,据调查说是一百多种l,也就是说有一百多种语言是可以直接跑在虚拟机上的,当然所谓的jvm虚拟机本身也是一种规范,Linux上由Linux的实现,unix上由unix的实现,java virtual Machine帮你屏蔽了操作系统的这些底层
    在这里插入图片描述

  • jvm与java无关
    java虚拟机怎么才能做到这么多语言都可以往上跑呢,关键的原因在于class这个东西,任何语言只要你能编译成class文件,符合class文件的规范你就可以仍在java虚拟机上去执行,所以,从jvm的角度讲,他是不看你任何的语言的,只要和
    class文件有关系,都是它的菜.
    在这里插入图片描述

  • jvm是一种规范,它就定义了java虚拟机应该能够执行什么等等…java虚拟机应该具备哪些模块,遇到什么样的指令应该做些什么样的东西.
    大家可以去oracle网站查看,每个版本不一样:
    https://docs.oracle.com/en/java/javase/13/
    https://docs.oracle.com/javase/specs/index.html

  • jvm是虚拟出来的一台计算机,既然它是一台虚拟出来的计算机,你就可以想象成一层单独的机器,那它就有自己的CPU,有自己的指令集,汇编语言,相当于自己是一个操作系统

  • 虚构出来的一太计算机
    字节码指令集(汇编语言)
    内存管理: 堆,栈,方法区等

常见的JVM的实现

三流的企业做产品,二流的企业做服务,一流的企业定标准,这就是定的标准,Oracle定了这一个java虚拟机的实现标准.
在这里插入图片描述

  • JDK,JRE,JVM
    JVM叫java的虚拟机只是来执行的,就是你所以东西都弄好之后它来执行的
    JRE运行时环境,java想要在虚拟机上运行,除了虚拟机之外,java的那些核心类库你得有
    JDK是java的开发工具包,包含了JRE和JVM
    在这里插入图片描述

  • Class File Format
    java虚拟机是以class文件为核心的,这class文件是什么呢?
    整个class文件的格式就是二进制字节流,这个二进制字节流是由java虚拟机来解释的

public class test{
}

编译完之后Build,再看反编译版本就已经有区别了,它自动帮你加了无参的构造方法,其实任何文件打开里面全都是0101二进制

public class test{
public test(){
}
}

这个class文件如果你用16进制的编译器打开之后看里面的内容是这么一个东西如下图,这个工具叫sublime
在这里插入图片描述
这个工具你可以选择八进制,十六进制,二进制,十进制

对十六进制来说,一个十六进制位就是四位,两个就是一个字节,前面的四个字节,指的就是文件的统一标识符,用十六进制打开,前几位一般都一样,看到CA FE BA BE这就是java编译完的class文件,四个字节;这部分叫做magic Number魔术
大家可以对照下图去解读,我这里是十六进制的:
在这里插入图片描述
注意:常量池是从1开始的,数组是从0开始,所以要减去1,从1开始的原因是:他有一个0存在那里,将来没准哪天有些引用指向,表示不指向任何常量池的一项,那时候就可以用0来表示,保留一个可能性.

  • ByteCode
    有很多可以观察ByteCode的方法
  1. javap -java自带的叫java命令
  2. JBE 他除了可以观察二进制码之外还可以直接修改
  3. JClassLib -IDEA中的插件,这个最常用
    这个插件用起来非常简单,当你安装完这个插件就会有这个选项了->show Bytecode with jclasslib
    在这里插入图片描述
    在这里插入图片描述

它分析的非常多:
->General information 通用的一些信息,前面图解也有说明这些信息的代表意思
在这里插入图片描述

->ConstantPool常量池里面的常量类型特别多,总而言之常量池是一个class里面最复杂的东西
->interfaces;接口类相关东西
->Fields:字段属性
->Methods:他会给我们加一个无参的构造方法
一个方法的汇编翻译完之后全都是下图这些东西,这些东西就是java的汇编,当作为一个java虚拟机来讲当它读到一个class文件里面内容的时候他就要去查表里代表的是哪条命令
其实这方法还有附加属性,最主要的就是code,就是这个方法的代码是怎么实现的,这个方法的具体的实现才是最重要的,当我们看到这个方法的时候我们回去里面找它的一条一条的命令
在这里插入图片描述
附加属性里面最重要的一项是方法表,也就是这个方法编译完成之后的字节码指令,那么jvm看到这个指令的时候首先会读这个指令进来,然后根据这个指令去查指令表,拿aload_o来说,在方法的局部变量里面的第0项,只要不是静态方法它永远都是this,放栈里之后进行第二条指令invokespecial特殊调用this的构造方法,然后jvm在根据指令一条一条的执行,当我们看到这个code的时候,最后一条指令是return

  • 扩展:jvm的每条指令在多线程是原子的嘛?
    JVM有8个指令是原子性
    lock(锁定) read(读取) load(读取) use(使用)
    assign(赋值) store(存储) write(写入) unlock(解锁)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值