理解JVM字节码,做点有意的事儿

作者:侯树成

来源:Tomcat那些事儿

 

JVM 字节码,做为虚拟机执行的指令,对于平时做 Java 应用开发来说,一直像蒙着一层神秘面纱,朦朦胧胧。

 

但其实理解了字节码指令,对于 Java 虚拟机的工作原理,对于基于「栈」的指令执行,对于一些 JVM 的新特性、语法都能更好的理解本质。

 

一般英文文章中介绍一些深入底层原理的时候,都喜欢用这个词:「under the hood」,本意是指汽车等引擎盖下,后来引申为一些底层原理。

 

什么是字节码?

Java 虚拟机的指令由一个字节长度的操作码(opcode)和紧随其后的可选的操作数(operand)构成,如下所示。

<opcode> [<operand1>, <operand2>]

比如将整型常量 100 压栈到栈顶的指令是 bipush 100,其中 bipush 是操作码,100 是操作数。字节码(bytecode)名字的由来是操作码的长度用一个字节表示。因为操作码长度只有一个字节长度,这使得编译后的字节码文件非常小巧紧凑,但也直接限制整个 JVM 操作码指令集的数量最多只能有 256 个,目前已经使用超过了 200 个。

 

大部分字节码指令是与类型相关的,比如 ireturn 指令用于返回一个 int 类型的数据,dreturn 指令用于返回一个 double 类型的数据,freturn 指令用于返回一个 float 类型的数据,这也使得字节码实际的指令类型远小于 200 个。

 

字节码使用大端序(Big-Endian)表示,即高位在前,低位在后的方式,比如字节码getfield 00 02,表示的是 getfiled 0x00<<8 | 0x02(getfield #2)。

 

字节码并不是某种虚拟 CPU 的机器码,而是一种介于源码和机器码中间的一种抽象表示方法,不过字节码通过 JIT(Just In Time)技术可以被进一步编译成机器码。

 

根据字节码的不同用途,字节码指令可以大概分为如下几类:

  • 加载和存储指令,比如 iload 将一个整型值从局部变量表加载到操作数栈; 

  • 控制转移指令,比如条件分支 ifeq;

  • 对象操作,比如创建类实例的指令 new;

  • 方法调用,比如 invokevirtual 指令用于调用对象的实例方法;

  • 运算指令和类型转换,比如加法指令 iadd;

  • 线程同步,比如monitorenter 和 monitorexit 这两条指令用于支持 synchronized 关键字的语义;

  • 异常处理,比如 athrow 显式抛出异常。

 

字节码是运行在 JVM 上的,为了能弄懂字节码,需要对 JVM 的运行原理有所了解。

 

而掀开JVM的盖,字节码指令也可以说是很重要的一部分了。理解了它,对于一些 ORM 框架等做的编译时的(Enhance)字节码增强,你就能知道他到底干了什么。

 

理解了字节码指令之后,可能就会抱怨其使用的繁琐。而ASM、Javassist 等工具就是免去你重新搬砖盖房子的,直接以更方便的API提供给用户,免除了手工解析的苦恼。

 

理解和掌握了 JVM 字节码,除了偶尔编辑和分析一下 class 文件,少数情况下通过ASM等增加或修改些指令外,其实还能做不少有意思的事儿。像类的加载时增强,Agent attach、Instrument实现类的 transform,运行时的retransform等...

 

如果想对JVM有更深次的理解,推荐阅读:《深入理解 JVM字节码》,本书分为字节码原理篇和应用篇。

第一部分是关于 class 文件的结构、字节码的工作原理、 Javac的编译原理,以及 ASM、Javassist工具的使用做了细致的介绍。此外还包含对于 Java Instrumentation 的原理,Lombok 这种 JSR 269的插件化注解的处理原理等也有介绍。

第二部分介绍了一些比较有意思的实战思路和尝试。像字节码在 Dubbo 通过Javassist实现动态代理的应用 、在 JaCoCo中对于代码覆盖率的实现。如果这些你觉得老生常谈,那软件的破解和防破解可能会让你耳目一新。

我们知道 Java 的 class 虽然经过了编译,但通过反编译工具可以轻松的查看源码,甚至不差分毫。所以书里对于破解提到了直接修改class 文件和通过 Java agent 的无痛破解两种方式。所以对于Java 应用,通过反编译能很快的了解到软件的实现思路,甚至对于商业软件会面临盗版、破解的风险。

不知攻怎么知道防,理解了破解的方式,对于书中介绍的混淆和通过自定义类加载器来加载加密的 class文件防,都是不错的思路。

另外,现在分布式应用、微服务系统越来越流行,给对应的分析和监控带来了不小的挑战,书中全链路分布式跟踪、通过ASM 操作字节码,实现 APM 工具,进行应用的性能分析、诊断等,都有借鉴意义。

 

 

本书正在参加当当网开学季大促,每满100-50的基础上,满200元再叠加立减40元!下单输入优惠码【EWAVRU】即可立减

点击链接了解详情并购买 

更多精彩回顾

书讯 |华章计算机拍了拍你,并送来了8月书单(下)

书讯 | 华章计算机拍了拍你,并送来了8月书单(上)

上新 | 首本深入讲解Linux内核观测技术BPF的书上市!
书单 | 《天才引导的历程》| 西安交通大学送给准大一新生的礼物

干货 | 机器人干活,我坐一边喝茶——聊聊最近爆火的RPA

收藏 | 揭秘阿里巴巴的客群画像

点击阅读全文购买

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值