JVM-基础知识

JVM基础知识

JVM结构图

简图
详细图

字节码文件

Java虚拟机不和包括Java在内的任何语言绑定,它只与字节码文件这种特定的二进制文件格式所关联.
Class文件结构不仅仅是JVM的执行入口,更是Java生态圈的基础和核心.

字节码文件内容是什么

字节码是一种二进制的类文件,他的内容是JVM指令,而不像C,C++经由编译器直接生成机器码(JIT后面进行了优化).

class文件编译器

分为前端编译器 就是javac(ecj,eclipse的增量编译器)编译器,他把咱们写的Java代码编译为字节码文件,还有后端的编译器就是JIT,运行时编译,能把字节码文件的执行命令再编译为native的本地执行代码,让运行效率更高(这也是Java说自己的运行效率基本等同于C语言的底气所在) 后面还有个aot提前编译

javac前端编译器的编译步骤

词法解析->语法解析->语义解析->生成字节码

哪些类型对应有class对象
  • class: 类对象都算,包括各种的内部类
  • interface: 接口
  • []: 数组
  • enum: 枚举
  • annotation: 注解
  • primitive type: 基本数据类型
  • void

字节码指令

是由一个字节长度的,代表着某种特定操作含义的操作码(opcode),以及跟随其后的零至多个代表此操作所需参数的操作数(operand)所构成.虚拟机中的许多指令并不包含操作数,只有一个操作码

字节码趣味题目

class文件结构

结构概述
  • 魔数
  • 每个class文件开头的4个字节的无符号整数称为魔数
  • 他的唯一作用是确定这个文件是否为一个能被虚拟机接受的有效合法的Class文件(魔数就是Class文件的标识符)
  • 魔数值固定为0xCAFFBABE不会改变
  • 之所以用魔数不用扩展名是出于安全方面的考虑(因为扩展名可以随意的更改)
  • Class文件版本
  • 排列在magic后的第5个和第6个字节所代表的含义就是编译的副版本号minor_version,而第7个和第8个字节就是编译的主版本号major_version
  • 验证字节码文件的主版本号和次版本号同样也是格式验证的任务之一,因为如果是高版本的JDK编译的字节码文件,自然不能在低版本的JVM中运行,否则JVM会抛出java.lang.UnsupportedClassVersionError异常
  • 常量池(一共是有21项,(其实大小是22,0表示不引用常量池))
  • constant_pool_count (常量池计数器):constant_pool_count的值等于常量池表中的成员数加1。常量池表的索引值只有在大于0且小于constant_pool_count时才会认为是有效的,对于long和 double类型有例外情况。
  • constant_pool [](常量池):constant_pool是一种表结构,以 1 ~ constant_pool_count - 1为索引。它包含class文件结构及其子结构中引用的所有字符串常量、类或接口名、字段名和其他常量。常量池中的每一项都具备相同的特征——第1个字节作为类型标记,用于确定该项的格式,这个字节称为tag byte (标记字节、标签字节)
  • 访问标识(或者说是标志)
  • 常量池后面就是访问标志,用两个字节来表示,其标识了类或者接口的访问信息,比如:该Class文件是类还是接口,是否被定义成public,是否是abstract,如果是类,是否被声明成final等等。
  • 类索引,父类索引,接口索引集合
  • 访问标志后的两个字节就是类索引;
  • 类索引后的两个字节就是父类索引;
  • 父类索引后的两个字节则是接口索引计数器。
  • 通过这三项,就可以确定了这个类的继承关系了。
  • 字段表集合(字段表用来描述类或者接口中声明的变量。这里的字段包含了类级别变量以及实例变量,但是不包括方法内部声明的局部变量)
  • fields_count (字段计数器): fields_count的值表示当前class文件fields表的成员个数。fields表中每个成员都是一个field_info结构,用于表示该类或接口所声明的类字段或者实例字段。
  • fields [](字段表): fields表中的每个成员都必须是一个fields_info结构的数据项,用 于表示当前类或接口中某个字段的完整描述。fields表描述当前类或接口声明的所有字段,但不包括从父类或父接口继承的那些字段。
  • 方法表集合(指向常量池索引集合,它完整描述了每个方法的签名,如果这个方法不是抽象的或者不是native的,那么字节码中会体现出来。)
  • methods_count (方法计数器):methods_count的值表示当前class文件methods表的成员个数。methods 表中每个成员都是一个method_info结构。
  • methods [](方法表):methods表中的每个成员都必须是一个method_info结构,用于表示当前类或接口中某个方法的完整描述。如果某个method_info结构的access_ flags项既没有设置 ACC_NATIVE 标志也没有设置ACC_ABSTRACT标志,那么该 结构中也应包含实现这个方法所用的Java虚拟机指令。
  • method_info 结构可以表示类和接口中定义的所有方法,包括实例方法、类方法、 实例初始化方法和类或接口初始化方法。methods表只描述当前类或接口中声明的方法,不包括从父类或父接口继承的方法。
  • 属性表集合(不同值的集合,它提供了额外的关于这个类的信息,包括任何带有RetentionPolicy.CLASS 或者RetentionPolicy.RUNTIME的注解)
  • attributes_count (属性计数器):attributes_count的值表示当前class文件属性表的成员个数。属性表中每一项都是一个attribute_info结构。
  • attributes [](属性表):属性表的每个项的值必须是attribute_info结构

class结构图标示意

访问标识表
标志名称标志值含义
ACC_PUBLIC0x0001是否为public类型
ACC_FINAL0x0010是否被声明为final,只有类可以设置
ACC_SUPER0x0020是否允许使用invokespecial字节码指令的新语义,jdk1.0.2之后编译出来的类这个标志默认为真
ACC_INTERFACE0x0200标志这个一个接口
ACC_ABSTRACT0x0400是否为abstract类型,对于接口和抽象类来说,此标志值为真,其他的为假
ACC_SYNTHETIC0x1000标志这个类并非由用户代码产生
ACC_ANNOTATION0x2000标志这是一个注解
ACC_ENUMx4000标志这是一个枚举
字段表访问标志

字段表访问标志

方法表访问标志

方法表访问标志

方法表结构

方法表结构

类的加载过程

类的加载过程

Loading(装载)阶段

  • 通过一个类的全限定名获取定义此类的二进制字节流
  • 将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构
  • 在内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口
类模板对象

类模板对象就是Java类在jvm当中的一个快照,jvm将从字节码文件中解析出的常量池,类字段,类方法等信息存储到类模板中,这样jvn在运行期间便能通过类模板获取java类中的任意信息,能够对Java的类成员变量遍历,也能调用方法.
反射的机制就是基于这一基础

jdk1.8之前存储在永久代 1.8以后存储在元空间

二进制流的获取方式
  • 通过文件系统读入class扩展名文件
  • 读入jar,war,zip等归档数据包
  • 数据库中读取类的二进制数据
  • 通过http请求远程的信息
  • 运行时直接生成一段class的二进制信息
数组类的加载

它比较特殊,因为数组类本身并不是由类加载器去创建的,而是由jvm在运行时根据需要而直接创建的,但是数组的元素类型仍然需要依靠类加载器去创建,过程如下:

  • 如果数组的元素类型是引用类型,那么就遵循定义的加载过程递归加载和创建数组的元素类型
  • jvm使用指定的元素类型和数组纬度来创建新的数组类
  • 如果数组类的元素类型是引用类型,数组类的可访问性就由数组元素的可访问性决定,否则数组的可访问性将被缺省定义为public

Linking(链接)阶段

  • 验证(Verify,保字节码是合法合理并且符合规范的)
  • 目的在于确保Class文件的字节流中包含信息符合当前虚拟机要求,保证被加载类的正确性,不会危害虚拟机自身安全。
  • 主要包括四种验证,文件格式验证,元数据验证,字节码验证,符号引用验证。
  • 准备(Prepare):
  • 为类的静态变量分配内存,并将其初始化为默认值.
  • 这里不包含用final修饰的static,因为final在编译的时候就会分配了,准备阶段会显式初始化;
  • 这里不会为实例变量分配初始化,类变量会分配在方法区中,而实例变量是会随着对象一起分配到Java堆中。

Java并不支持boolean类型,对于boolean类型,内部实现是int,由于int的默认值是0,所以boolean的默认值就是false

解析(Resolve)阶段

  • 将常量池内的符号引用转换为直接引用的过程。
  • 事实上,解析操作往往会伴随着JVM在执行完初始化之后再执行,符号引用就是一组符号来描述所引用的目标。符号引用的字面量形式明确定义在《java虚拟机规范》的Class文件格式中。在解析阶段,jvm根据字符串的内容找到内存区域中相应的地址,然后把符号引用替换成直接指向目标的指针、句柄、偏移量等,这些直接指向目标的指针、句柄、偏移量就被成为直接引用。
  • 解析动作主要针对类或接口、字段、类方法、接口方法、方法类型等。对应常量池中的CONSTANT_Class_info、CONSTANT_Fieldref_info、CONSTANT_Methodref_info等。
设置栈的大小

现在默认是1Mb大小(不宜设置的过大),用**-Xss size(即 -XX:ThreadStackSize)**来设置,一般默认为512-1024k,取决于操作系统,栈的大小决定了函数调用的最大可达深度

初始化阶段

简单来说就是给类的静态变量赋予正确的初始值

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/25551.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

github在线编程

github在线编程 文章目录 github在线编程两种区别演示项目 Ruoyi-VueGitHub Codespaces 演示github 访问项目使用 GitHubCodeSpace 打开该项目查看运行环境安装运行环境初始化myql数据安装 redis运行前端运行后端前后端运行成功测试安装相关插件 GitPod 演示 说明: 目前总结 gi…

把玩数据在内存中的存储

前言:时光如梭💦,今天到了C语言进阶啦😎,基础知识我们已经有了初步认识, 是时候该拔高拔高自己了😼。 目标:掌握浮点数在内存的存储,整形在内存的存储。 鸡汤&#xff1a…

好玩!AI文字RPG游戏;播客进入全AI时代?LangChain项目实践手册;OpenAI联创科普GPT | ShowMeAI日报

👀日报&周刊合集 | 🎡生产力工具与行业应用大全 | 🧡 点赞关注评论拜托啦! 🤖 Microsoft Build 中国黑客松挑战赛,进入AI新纪元 近期,伴随着人工智能的新一轮浪潮,Hackathon (黑…

【网络协议详解】——OSPF协议(学习笔记)

目录 🕒 1. 概述🕒 2. 相关概念🕘 2.1 基本思想🕘 2.2 区域及路由🕘 2.3 链路状态数据库🕤 2.3.1 点到点网络🕤 2.3.2 点到多点网络🕤 2.3.3 广播网络与非广播多址接入网络&#x1f…

反射枚举

1、定义 java的反射机制是在运行状态中,对于任意一个类,都能直到这个类的所有属性和方法;对于任意一个对象,都能够调用他的任意方法和属性,既然能够拿到那么,我们就可以修改部分类型信息;这种动…

软考A计划-电子商务设计师-计算机系统基础知识

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例 👉关于作者 专注于Android/Unity和各种游戏开发技巧,以及各种资源分享&am…

Delphi11的多线程ⓞ,附送图片处理代码

Delphi11的多线程ⓞ OLD Coder , 习惯使用Pascal 接下来准备启用多线程,毕竟硬件多核,Timer不太爽了(曾经的桌面,都是Timer——理解为“片”) 突然想写写,不知道还有多少D兄弟们在。 从源码开始 用D11之…

mybatisplus递归传递多个参数 | mybatisplus传递多个参数获取层级数据 | mybatisplus传递多个参数获取树形数据

搜索关键字: mybatisplus关联查询传递参数|"select""树形结构"|"select""树形结构""传参"| "select""many""传参"| "select""column""传参" 1、…

内置工具横向移动

IPCSchtasks IPC: IPC$是共享"命令管道"的资源,它是为了让进程通信而开放的命名管道,连接双方可以建立安全的通道并以此通道进行加密数据交换,从而实现对远程计算机的访问。 利用条件: 1、开放139、445 2、目标开启…

SAP-MM-采购申请审批那些事!

1、ME55不能审批删除行项目的PR 采购申请审批可以设置行项目审批或抬头审批。如果设置为抬头审批时,ME55集中审批时,就会发现有些采购申请时不能审批的, 那么这些采购申请时真的不需要审批么?不是的,经过核对这些采购申…

【每周一书】--(认知觉醒)思考:如何用清爽的情绪面对内卷的当下?

【每周一书】--(认知觉醒)思考:如何用清爽的情绪面对内卷的当下? 认知觉醒:开启自我改变的原动力焦虑:焦虑的根源完成焦虑定位焦虑选择焦虑环境焦虑难度焦虑 如何拥有清爽的情绪,释放焦虑情绪 认…

STM32F407单片机HAL库CAN2不能接收数据解决方法

最近在使用stm32F407的片子调试can通信,直接在正点原子的代码上修改调试,调试can1的时候,基本没啥问题,收发都正常,使用查询模式和中断模式都可以。但是当修改到can2的时候,可以正常发送数据,但…

WPF 热重载失效了

关于 热重载官方说明: WPF 和 UWP 应用的 XAML 热重载是什么Introducing the .NET Hot Reload experience for editing code at runtime 热重载简单来说,就是点击运行程序后,修改 XAML 代码,应用程序会实时的显示你的修改 为…

Python入门(十三)函数(一)

函数(一) 1.函数概述2.函数定义2.1向函数传递信息2.2实参和形参 作者:xiou 1.函数概述 函数是带名字的代码块,用于完成具体的工作。要执行函数定义的特定任务,可调用该函数。需要在程序中多次执行同一项任务时&#…

中间件SOME/IP简述

SOME/IP SOME/IP 不是广义上的中间件,严格的来讲它是一种通信协议,但中间件这个概念太模糊了,所以我们也一般称 SOME/IP 为通信中间件。 SOME/IP 全称是 Scalable service-Oriented MiddlewarE over IP。也就是基于 IP 协议的面向服务的可扩…

使用Python绘制M2货币供应率曲线

M2广义货币供应量:流通于银行体系之外的现金加上企业存款、居民储蓄存款以及其他存款,它包括了一切可能成为现实购买力的货币形式,通常反映的是社会总需求变化和未来通胀的压力状态。近年来,很多国家都把M2作为货币供应量的调控目…

ChatGPT国内免费使用方法【国内免费使用地址】

当下人工智能技术的快速发展,聊天机器人成为了越来越多人们日常生活和工作中的必备工具。如何在国内免费使用ChatGPT聊天机器人,成为了热门话题。本文将为你详细介绍ChatGPT国内免费使用方法,让你轻松拥有聊天机器人助手,提高工作…

Vue3 小兔鲜:Pinia入门

Vue3 小兔鲜:Pinia入门 Date: May 11, 2023 Sum: Pinia概念、实现counter、getters、异步action、storeToRefs保持响应式解构 什么是Pinia Pinia 是 Vue 的专属状态管理库,可以实现跨组件或页面共享状态,是 vuex 状态管理工具的替代品&…

论文学习笔记:Swin Transformer: Hierarchical Vision Transformer using Shifted Windows

论文阅读:Swin Transformer: Hierarchical Vision Transformer using Shifted Windows 今天学习的论文是 ICCV 2021 的 best paper,Swin Transformer,可以说是 transformer 在 CV 领域的一篇里程碑式的工作。文章的标题是一种基于移动窗口的…

C++异步调用方法

C之future和promise future和promise的作用是在不同线程之间传递数据。使用指针也可以完成数据的传递,但是指针非常危险,因为互斥量不能阻止指针的访问;而且指针的方式传递的数据是固定的,如果更改数据类型,那么还需要…