当前位置: 首页 > news >正文

JVM虚拟机入门到实战(持续更新中)

基础篇-初识JVM

JVM本质上是一个运行在计算机上的程序,它的职责是运行java字节码文件

写好的java文件先由javac编译为class文件,但class文件上的指令是无法直接在计算机中运行的,这是就要把class文件交由java虚拟机(JVM)解释,即转换为机器码,最后在计算机中运行文件。

JVM的功能

  • 解释和运行
    • 对字节码文件中的指令实时的解释称机器码,让计算机执行
  • 内存管理
    • 自动为对象、方法等分配内存
    • 自动的垃圾回收机制,回收不再使用的对象
  • 即时编译
    • 对热点代码进行优化,提升执行效率

JVM的功能-即时编译

Java语言如果不做任何优化,性能是不如C,C++等语言的。

Java语言需要将java文件先编译再实时解释为机械码才能交由计算机运行。而C/C++等语言在编译的时候就能直接转换为机械码文件进而直接由计算机执行。

Java进行实时解释主要是为了实现跨平台特性。而C和C++则不支持跨平台。

即时编译会在JVM将文件转换为机械码后将其保存到内存中去,等再次要执行时就能直接调用内存中的文件去执行。这优化了Java的性能,使其追赶上C和C++等语言。

常见的JVM

字节码文件详解

Java虚拟机的组成

  • 类加载器ClassLoader:加载class字节码文件中的内容到内存中去。
  • 运行时数据区域(JVM管理的内存):负责管理JVM使用到的内存,比如创建对象和销毁对象。
  • 执行引擎:将字节码文件中的指令解释为机器码,同时使用即时编译器优化性能。
  • 本地接口:调用本地已经编译的方法,比如蓄奴籍中提供方C/C++的方法。

本地接口执行引擎中的解释器属于Java虚拟机底层源码的部分且程序员无法对其进行修改,所以了解即可。

字节码文件的组成

正确打开class文件

字节码文件中保存了源代码比那以后的内容,以二进制的方式存储,无法用记事本打开阅读。强行打开里面都是乱码,无法正常阅读。

  • 这里推荐 jclasslib 工具查看字节码文件。
  • Github地址:https://gitHub.com/ingokegel/jclasslib

class文件基本就包含这5项内容

  • 基础信息:魔数、字节码文件对应的Java版本还访问标识(public final等)父类和接口
  • 常量池:保存了字符串常量、类或接口名、字段名主要在字节码指令中使用
  • 字段:当前类或接口声明的字段信息
  • 方法:当前类或接口声明的方法信息字节码指令
  • 属性:类的属性,比如源码的文件名,内部类的列表等

字节码文件组成部分-Magic魔数

上面是两个字节澳门文件用记事本打开的显示出的内容,可以看出两个开头的内容相同,相同的内容就是魔数。

  • 文件是无法通过文件扩展名来确定文件类型的,文件扩展名可以随意修改,不影响文件的内容
  • 软件使用文件的头几个字节(文件头)去校验文件的类型,如果软件不支持该种类型就会出错
  • Java字节码文件中,讲文件头称为magic魔数

字节码文件的组成部分-主副版本号

  • 主副版本号指的是编译字节码文件的JDK版本号,主版本号用来标识大版本号,JDK1.0-1.1使用了45.0-45.3,JDK1.2是46之后每升级一个大版本就加1;副版本号是当主版本号相同时作为区分不同版本的标识,一般只需要关心主版本号。
  • 版本号的作用主要是判断当前字节码的版本和运行时的JDK是否兼容。

1.2之后大版本号计算方法就是:主版本号 - 44    比如主版本号52就是JDK8。

案例:主版本号不兼容导致的错误

它说类文件有错误的版本52.0(即类文件的版本号为52.0-JDK8),而应为50.0(即文件的运行环境版本号是50.0-JDK6)。无法访问 org.apache,commons.lang3.RandomstrineUtils说明是依赖需要的版本号是JDK8,而项目的环境是JDK6.

两种解决办法:

  1. 升级项目JDK版本(不推荐,容易引发其他的兼容性问题,并且需要大量的测试
  2. 将第三方依赖的版本号降低或者更换依赖,以满足JDK版本的要求(建议采用

字节码文件的组成部分-常量池

  • 常量池中的数据都有一个便不好,编号从1开始。在字段或者字节码指令中通过编号可以快速的找到相应的数据。
  • 字节码指令中通过编号引用常量池的过程叫做符号引用

如果在Java中定义了两个及以上的相同值的参数,其在常量池中只会开辟一个空间专门存放这个值

字段下面会存放字段的名字和值在常量池中的位置编号,如果是值如字符串类型的值会指向字符串类型,然后再指向字面量的值。字段名则会直接指向字面量的值。

字节码文件的组成-方法

说方法就要引入两个额外的东西。

  1. 操作数栈:操作数栈是JVM对数据进行处理操作是临时存储数据的地方
  2. 局部变量表数组:局部变量表数组是局部变量的存放位置,是一个数组,0索引处是在main方法处引入的args,从1开始就是我们自己定义的局部变量按顺序存放。
    public static void main(String[] args) {int i = 0;int j = i + 1;//下面是上面代码的字节码方法
//        0 iconst_0    将0压入操作数栈顶(iconst_数字:把数字压入操作数栈顶)
//        1 istore_1    将操作数栈顶的变量的值保存到局部变量表数组索引为1的位置
//        2 iload_1     把局部变量表数组索引为1的位置的值复制到操作数栈顶
//        3 iconst_1    将1压入操作数栈顶
//        4 iadd        将操作数栈顶两个值弹出,并计算它们的和,将结果压入操作数栈顶
//        5 istore_2    将操作数栈顶的变量的值保存到局部变量表数组索引为2的位置
//        6 return      最后返回}
}

如果在面试时,面试官问你

有些人可能会回答 i = 1 也有人会回答 i = 0 ,答案是 i = 0,但为什么呢,如果没学过Java虚拟机,你可能会回答因为 i = i++ 的操作是先赋值再 +1,i已经赋值了,+1是对数值进行+1,已经不会对 i 产生影响了,但这绝对不是面试官想要的答案。

这时我们需要从JVM的角度来回答,根据字节码指令来分析。

    public static void main(String[] args) {int i = 0;i = i++;//字节码指令如下:
//        0 iconst_0        将0压入操作数栈顶
//        1 istore_1        将栈顶的0保存到数组索引1中
//        2 iload_1         将数组索引1中的值压入栈顶
//        3 iinc 1 by 1     将数组索引1中的值加1(注意:iinc i by j 是直接在数组中进行操作的,是把数组中索引为i处的值加j)
//        6 istore_1        将栈顶的0保存到数组索引1中
//        7 return          返回}
}

由上可知,在JVM中可不是先赋值再加1的,只不过是因为++操作直接在数组中进行导致后面赋值把++的操作给覆盖掉了。下面我们也看一下++i 的字节码命令

    public static void main(String[] args) {int i = 0;i = ++i;//字节码指令如下:
//        0 iconst_0        将0压入操作数栈顶
//        1 istore_1        将栈顶的变量的值保存到数组1中
//        2 iinc 1 by 1     将数组1的值加1
//        5 iload_1         将数组1的值的值压入栈顶
//        6 istore_1        将栈顶的变量的值保存到数组1中
//        7 return}

字节码文件常用工具的使用

javap -v命令

  • javap是JDK自带的反编译工具,可以通过控制台查看字节码文件的内容。适合在服务器上查看字节码文件里的内容。
  • 直接输入javap查看所有参数
  • 输入 javap -v字 节码文件名称 查看具体的字节码信息,如果需要发送给其他人可以直接在最后面加上 > 文件地址 来直接生成文件。(如果是jar包需要先使用jar -xvf命令解压)

jclasslib插件

在idea里下载jclasslib的插件

Arthas

  • Arthas 是一款线上监控诊断产品,通过全局视角实时査看应用load、内存、gc、线程的状态信息,并能在不修改应用代码的情况下,对业务问题进行诊断,大大提升线上问题排查效率。
  • 官网:https://arthas.aliyun.com/doc/ 与arthas相关的所有指令都可以在官网中查看。
  • 下载地址:Releases · alibaba/arthas

下载下来之后解压,然后在解压后的地址处输入cmd调出命令提示符,然后输入指令java -jar arthas-boot.jar

输入指令之后你能看到你启动的程序,它会自动为你的启动类带上包名,然后你输入最前面方括号里面的数字如1就能进入你选择的程序内进行操作。

dump命令,dump可以把类的字节码文件保存到你指定的目录里面去

dump -d 目录 类的权限名(即包名.类名)

这里的路径中间的斜杠要写 / 否则会生成到默认路径下。

jad命令,jad命令能把你的字节码文件发编译成代码。

jad 类的权限名

类的加载周期

http://www.dtcms.com/a/512791.html

相关文章:

  • 苏州网站建设与网络营销网络销售的好处和意义
  • 免费wordpress主题分享seo网站建站公司的主页
  • 外贸网站宗旨网站建设包括哪些方面
  • 什么外设选择开漏,什么外设选择推挽?
  • HTML 标签及推荐嵌套结构
  • 优先算法专题十二——栈
  • Flare 少样本学习嵌入式agent
  • Windows 系统下 n8n 自动化工具的完整部署指南
  • 138ip地址查询网站php wordpress joom
  • 贴片电阻封装尺寸与功率等级对照表及选型指南:从0201到2512的全面解析
  • 基于单片机的智能灯光控制系统设计与实现(论文+源码)
  • TypeScript 高级类型工具:Partial, Required, Record 的妙用与陷阱
  • 网站建设的感想和建议做网站需要用c语言吗
  • 做网站买域名怎么弄做网站推广需要哪些知识
  • HTML5网站建设案例深圳专业企业网站制作哪家好
  • 虚拟机产品有哪些,有啥区别,如何安装
  • 2025年低代码平台选型指南
  • 在线支付的网站怎么做百度推广会帮你做网站不
  • 广州网站建设多少钱浙江核酸检测查验
  • LRU缓存淘汰算法Java实现
  • 合肥搭建网站建设厅安全员证
  • 定制网站开发接私活临桂建设局网站
  • C++蓝桥杯之指针10.20(竞赛中很少使用)
  • 平安大模型面试题:Self-Attention 原理与多头注意力设计
  • 手机网站是怎么做的邢台最近发生的新闻
  • 三周期共振强度系数的量化模型
  • swarm集群部署
  • 建设网站的工作wordpress更改导航栏样式
  • 企业网站建设时间表廊坊哪里有做阿里巴巴网站的
  • 使用 mina-sshd 库通过 SCP 上传文件并解决无法上传大文件的问题