01.基础篇:初始jvm

1.什么是jvm

java Virtual Machine 中文译名:java虚拟机

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

主要是 .java文件 通过 javac命令编译为 .class(字节码文件)文件 进而通过java命令 运行代码

1.1 jvm的三大核心功能

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

java的即时编译,主要是为了支持跨平台的特性

对相同的字节码文件,通过即时编译,可以实现在不同的平台上生成不同的机器码

1.2 即时编译 

            jvm提供了即时编译 JIT 进行性能的优化,最终能达到接近c、c++的运行性能甚至在特定的情况下实现超越

1.2.1 常见的JVM 

名称

作者

支持版本

社区活跃度

特性

适用场景

HotSpot

(Oracle JDK)

Oracle

所有版本

高(闭源)

使用最广泛,稳定可靠,社区活跃,JIT支持

Oracle JDK默认虚拟机

默认

HotSpot

(Open JDK)

Oracle

所有版本

同上

开源,OpenJDK默认虚拟机

默认

对jdk有二次开发需求

GraalVM

Oracle

11,17,19

企业版支持8

多语言支持Ruby、python、C++等

高性能、JIT、AOT支持

微服务、云原生架构,需要多语言混合编程

Dragonwell JDK

龙井

Alibaba

标准版 8,11,17

扩展版 11,17

基于Open Jdk的增强

高性能、bug修复、安全性提升

JWarmup、ElasticHeap、Wisp特性支持

电商、物流、金融领域对性能要求比较高

Eclipse Openj9

(原IBM j9)

IBM

8,11,17,19,20

高性能、可扩展

JIT、AOT特性支持

微服务、云原生架构

1.2.2 java虚拟机规范:

  • 《Java虚拟机规范》由Oracle指定,内容主要包含了java虚拟机在设计和实现时需要遵守的规范,主要包含class字节码文件的定义、类和接口的加载和初始化、指令集等内容
  • 《Java虚拟机规范》是对虚拟机设计的要求,而不是对java设计的要求,也就是说虚拟机可以运行在其他的语言,比如Groovy、Scala生成的class字节码文件之上      

1.2.3 HotSpot的发展历程

1.3 字节码文件详解

            jvm的组成

1.4 字节码文件的组成

1.4.1 应用场景: 

int i=0;i=i++; //最后i等于多少? //java的反射如何实现的?

1.4.2 解决工作中的实际问题:

        1. 版本冲突

        2. 系统升级

1.4.3 字节码的正确打开方式

        字节码文件中保存了源代码编译之后的内容,以二进制的方式存储,无法直接用记事本打开阅读

        推荐使用工具 工具查看字节码文件

1.4.4 字节码文件的组成

     

1.4.4.1 基本信息

     Magic 魔数——字节码文件前四个字节是由人为生成的

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

文件类型

字节数

文件头

JPEG(jpg)

3

FFDBFF

PNG(png)

4

89504E47(文件尾也有要求)

bmp

2

424D

XML(xml)

5

3C3F786D6C

AVI()

4

41564920

java字节码文件

4

CAFEBABE

主副版本号

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

       解决方案:

                    1. 升级jdk版本

                    2. 将第三方依赖的版本号降低或者更换依赖,以满足jdk版本的要求

访问标识

             标识是类还是接口、注解、枚举、模块

             标识public final abstract

1.4.4.2 常量池
  • 字节码文件中的常量池的作用:避免相同的内容重复定义,节省空间
  • 常量池中的数据都有一个编号,编号从1开始。在字段或者字节码指令中通过编号可以快速的找到对应的数据。
  • 字节码指令通过编号引用到常量池的过程称之为符号引用
1.4.4.3 方法

            一个非常有意思的面试题:int i=0;i=i++; 最终i的值是多少 最终结果为 i=0.                

  • 字节码中的方法区域是存放字节码指令的核心位置,字节码指令的额内容存放在方法的code属性中
int i=0; 
int j=i+1;

         

由于代码直接对局部变量表进行累加,而后将操作数栈中的值存放到局部变量表中,操作数栈中数据没有进行操作;故最终结果为0;

1.4.5 玩转字节码的常用工具

1.4.5.1 javap -v命令

输入javap -v 字节码文件名称 查看具体的字节码信息 。(如果是jar包需要先使用jar -xvf 命令解压)

1.4.5.2 通过jclasslib 查看字节码 
1.4.5.3 使用arthas
  • Arthas是一款线上监控诊断工具,通过全局视角实时查看应用load、内存、gc、线程的状态信息,并能在不修改代码的情况下,对业务问题进行诊断,大大提升线上问题排查效率

  • 官网 简介 | arthas

arthas阿尔萨斯指令入门学习

  • dashboard 显示系统的实时数据面板

参数名称

参数说明

i

刷新实时数据的时间间隔(ms),默认5000ms

n

刷新实时数据的次数

  • dump 将jvm中运行的字节码文件复制到指定目录下,适用场景:批量下载指定包目录的class字节码

参数名称

参数说明

class-pattern

类名表达式匹配

[c:]

类所属 ClassLoader 的 hashcode

[classLoaderClass:]

指定执行表达式的 ClassLoader 的 class name

[d:]

设置类文件的目标目录

[E]

开启正则表达式匹配,默认为通配符匹配

  • jad 将jvm中实际运行的class的byte code 反编译成 .java 代码,便于你理解业务逻辑;如需批量下载指定包的目录的class字节码文件可以参考dump 

参数名称

参数说明

class-pattern

类名表达式匹配

[c:]

类所属 ClassLoader 的 hashcode

[classLoaderClass:]

指定执行表达式的 ClassLoader 的 class name

[E]

开启正则表达式匹配,默认为通配符匹配

    

        案例分析:使用阿里arthas定位线上出现的字节码问题

        背景:小李的团队昨天对系统进行了升级修复了某个bug,但是升级完之后发现bug还是存在,小李怀疑是因为没有把最新的字节码文件部署到服务器上,请使用阿里的arthas去确认升级完的字节码文件是不是最新的。

        解决方案:

  1. 在产生问题系统的服务器上面部署Arthas
  2. jad命令反编译获取java文件
  3. 查看java代码是否时更改后的版本
  • 29
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值