JVM面试(一)什么是虚拟机?什么是class文件?

embedded/2024/9/24 17:17:24/

什么是java虚拟机

如果通俗点来讲,我们在电脑上一行行敲出来的代码,电脑本身是不认识的,最终是要转成电脑可以运行的101001这种字节。

但是这些我们又不可能手动来转换,所以呢,就需要一个工具,来将我们敲出来的代码,转换成电脑可以认识的命令来进行执行。

为了使用方便,就把这个可实时运行的程序,封装取来,拿到任何地方都可以使用。而且因为最支持的语言就是java,所以取一个名字叫做java虚拟机

那在真正使用的时候,我们到底有接触吗?

有, 就是每个java开发人员都要在电脑上安装的运行环境,JRE,这个就包含了java的虚拟机,还有一些基础的类库(也就是基础的jar包)。
那有的同学就说了,我们没有安装JRE,只安装了JDK啊。

对,JDK中,包含了java开发时候一些常用的工具包(jar/lib),同时还包含了JRE,以及编译器,
编译器就是我们配置jdk环境之后,都会输入的一个命令“javac”,作用就是将我们的开发文件".java" ,编译为".class"

".class"文件就是虚拟机运行时候可识别的文件,也就是说我们开发是java文件,虚拟机运行之前将其先编译为class文件,用这些class文件在虚拟机中运行,与计算机本身产生交互。

什么是跨平台?

为什么java语言可以实现跨平台? 就是因为编译之后,可以带着虚拟机,在任何地方运行。
并且,其他语言中,只要编译为class文件,都可以在虚拟机中运行,这样就能与java文件产生交互,这就叫跨平台,如下图:
在这里插入图片描述
也就是说,其实java虚拟机,并不是与java语言强相关。其他语言只要编译为class文件,就都可以在java虚拟机中运行,这个就叫做跨平台。

什么是class文件?

就是上面我们说过的,java虚拟机可识别的文件,由我们开发出来的java文件编译出来。
结构如下
在这里插入图片描述

  • ⽆符号数属于基本的数据类型,以u1、u2、u4、u8来分别代表1个字节、2个字节、4个字节和8个 字节的⽆符号数,⽆符号数可以⽤来描述数字、索引引⽤、数量值或者按照UTF-8编码构成字符串值。
  • 表是由多个⽆符号数或者其他表作为数据项构成的复合数据类型,为了便于区分,所有表的命名都习惯性地以“_info”结尾。表⽤于描述有层次关系的复合结构的数据,整个Class⽂件本质上也可以视作是⼀张表,这张表由表6-1所示的数据项按严格顺序排列构成。

魔数和主次版本号

魔数固定为CAFEBABE
次版本号在jdk12之前均没被使⽤,默认为0。主版本号如jdk8中对应为⼗进制的版本号为52;

常量池

(constant_pool_count)常量池计数器,从1开始计数,表示class中常量池的⼤⼩。
常量池中主要存放两⼤类常量:字面量(Literal)和符号引用(Symbolic References)。字面量比较接近于Java语⾔层⾯的常量概念,如文本字符串、被声明为final的常量值等。而符号引用则属于编译 原理方面的概念,主要包括下面几类常量:

  • 被模块导出或者开放的包(Package)
  • 类和接⼝的全限定名(Fully Qualified Name)
  • 字段的名称和描述符(Descriptor)
  • ⽅法的名称和描述符
  • ⽅法句柄和⽅法类型(Method Handle、Method Type、Invoke Dynamic)
  • 动态调⽤点和动态常量(Dynamically-Computed Call Site、Dynamically Computed Constant)

Java代码在进行Javac编译的时候,并不像C和C++那样有“连接”这⼀步骤,而是在虚拟机加载Class 文件的时候进行动态连接。也就是说,在Class文件中不会保存各个方法、字段最终在内存中的布局信息,这些字段、方法的符号引用不经过虚拟机在运行期转换的话是无法得到真正的内存入口地址,也就无法直接被虚拟机使用的。当虚拟机做类加载时,将会从常量池获得对应的符号引用,再在类创建时或运行时解析、翻译到具体的内存地址之中。

PS:上面这段话有点拗口,简单总结来说,就是虚拟机的运行并不直接与内存产生联系,而是在的请求创建的线程中,再与内存产生联系,线程拿到数据拷贝进行处理。

访问标志

在常量池结束之后,紧接着的2个字节代表访问标志(access_flags),这个标志用于识别一些类或者接口层次的访问信息,包括:这个Class是类还是接接口;是否定义为public类型;是否定义为abstract 类型;如果是类的话,是否被声明为final;等等

类索引、父类索引与接口索引集合

  • 类索引(this_class)和父类索引(super_class)都是⼀个u2类型的数据,而接口索引集合(interfaces)是⼀组u2类型的数据的集合,Class文件中由这三项数据来确定该类型的继承关系。
  • 类索引用于确定这个类的全限定名,父类索引⽤于确定这个类的父类的全限定名。
  • 由于Java语⾔不允许多重继承,所以父类索引只有⼀个,除了java.lang.Object之外,所有的Java类都有父类,因此除了java.lang.Object外,所有Java类的⽗类索引都不为0。
  • 接⼝索引集合就⽤来描述这个类实现了哪些接口,这些被实现的接⼝将按implements关键字(如果这个Class⽂件表示的是⼀个接口,则应当是extends关键字)后的接口顺序从左到右排列在接口索引集合中。

字段表集合

字段表(field_info)用于描述接⼝或者类中声明的变量。Java语⾔中的“字段”(Field)包括类级变量以及实例级变量,但不包括在方法内部声明的局部变量。

方法表集合

方法表⽤于描述接⼝或类中声明的方法。⽅法表的结构如同字段表⼀样,依 次包括访问标志(access_flags)、名称索引(name_index)、描述符索引(descriptor_index)、属性表集合(attributes)几项。

对于方法里的Java代码,经过Javac编译器编译成字节码指令之后,存放在方法属性表集合中⼀个名为“Code”的属性里面

属性表集合

属性表(attribute_info)。Class文件、字段表、方法表都可以携带自己的属性表集合,以描述某些场景专有的信息。


http://www.ppmy.cn/embedded/103855.html

相关文章

第十五章 rust中进行windows系统开发

注意 本系列文章已升级、转移至我的自建站点中,本章原文为:rust中进行Windows系统开发 目录 注意一、前言二、指针三、windows四、字符串一、前言 作为系统级语言,rust可以很容易的和C++一样进行系统级编程,但实际操作后我相信你会遇到相当多的问题。 比如以本文要介绍的…

vue3手动写一个图片懒加载的插件

关于图片懒加载,网上自然是有许多形形色色的成品的,但是现在我们自己来实现一个图片懒加载的功能 实现原理: 主要利用了js提供的一个新方法,IntersectionObserver用于监听元素是否在页面可视区域, 用法: C…

HTTP 缓存

一、概述 1.HTTP缓存的基本原理是将Web资源(如HTML,CSS,JavaScript,图片等)保存在客户端或中间代理服务器上,后续的请求可以直接使用客户端或代理服务器上缓存的资源,而不必重新从服务器上获取。 2.HTTP缓存分为强制…

CSS\JS实现页面背景气泡logo上浮效果

效果图&#xff1a; 单容器显示气泡&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Bu…

深入详解 C# Task.Run异步任务

目录 Task.Run Task.Run 的底层原理 默认并发数量 控制并发 使用 SemaphoreSlim 代码解析 使用 Parallel.ForEach 代码解析 注意事项 自定义任务调度器 代码解析 使用自定义任务调度器&#xff1a; 总结 Task.Run Task.Run 是 .NET 中创建和启动异步任务的一种便…

景联文科技提供运动数据采集服务

运动数据的重要性 运动数据的收集与分析对于提升个人健康管理和运动表现具有重要意义。 通过收集心率、步态、速度等生理和运动参数&#xff0c;不仅可以为运动员提供个性化的训练方案&#xff0c;帮助其优化表现&#xff0c;还能早期发现并预防伤病。对于普通健身者而言&…

vscode和edge浏览器等鼠标输入光标变透明

本人是AMD的APU会出现这种情况。它的gpu加速有些问题。 都是要关闭gpu硬件加速功能。edge浏览器好找。vscode是通过以下方法。 要关闭VSCode的硬件加速功能&#xff0c; ‌通过配置文件调整‌&#xff1a; 打开VSCode的设置&#xff08;通过按下CtrlShiftP或CmdShiftP打开命令…

81、k8s网络配置以及k8s拉取私有仓库

一、k8s架构安装部署 k8s架构master 192.168.168.81 docker、kubeadm、kubelet、kubectl、flannel node01 192.168.168.82 docker kubeadm kubelet kubectl flannel node02 192.168.168.83 docker、kubeadm、kubelet、kubectl、flannel#关闭防火墙 [rootk8s1 ~]# sys…