从底层入手,解析字节码加强和Btrace应用

这篇文章聊下字节码和相关的应用。java

一、机器码和字节码

机器码(machine code),学名机器语言指令,有时也被称为原生码(Native Code),是电脑的CPU可直接解读的数据。git

一般意义上来理解的话,机器码就是计算机能够直接执行,而且执行速度最快的代码。程序员

用机器语言编写程序,编程人员要首先熟记所用计算机的所有指令代码和代码的涵义。手编程序时,程序员得本身处理每条指令和每一数据的存储分配和输入输出,还得记住编程过程当中每步所使用的工做单元处在何种状态。这是一件十分繁琐的工做,编写程序花费的时间每每是实际运行时间的几十倍或几百倍。并且,编出的程序全是些0和1的指令代码,直观性差,还容易出错。github

字节码(Bytecode)是一种包含执行程序、由一序列 op 代码/数据对 组成的二进制文件。字节码是一种中间码,它比机器码更抽象,须要直译器转译后才能成为机器码的中间代码。编程

一般状况下它是已经通过编译,但与特定机器码无关。字节码一般不像源码同样可让人阅读,而是编码后的数值常量、引用、指令等构成的序列。api

字节码主要为了实现特定软件运行和软件环境、与硬件环境无关。字节码的实现方式是经过编译器和虚拟机器。编译器将源码编译成字节码,特定平台上的虚拟机器将字节码转译为能够直接执行的指令。数组

字节码的典型应用为Java bytecode。字节码在运行时经过JVM(JAVA虚拟机)作一次转换生成机器指令,所以可以更好的跨平台运行。安全

二、字节码加强技术

Java字节码加强指的是在Java字节码生成以后,对其进行修改,加强其功能,这种方式至关于对应用程序的二进制文件进行修改。Java字节码加强主要是为了减小冗余代码,提升性能等。工具

实现字节码加强的主要步骤为:性能

(1)修改字节码

在内存中获取到原来的字节码,而后经过一些工具(如 ASM,Javaasist)来修改它的byte[]数组,获得一个新的byte数组。

(2)使修改后的字节码生效

有两种方法:

  • 自定义ClassLoader来加载修改后的字节码;
  • 替换掉原来的字节码:在JVM加载用户的Class时,拦截,返回修改后的字节码;或者在运行时,使用Instrumentation.redefineClasses方法来替换掉原来的字节码;

三、字节码加强有哪些实现

字节码加强技术有如下这些:

  • 动态代理
  • CGLIB
  • Javassist
  • asm

以 ASM 为例, 使用它能够动态修改类、方法,甚至能够从新定义类,连 CGLib 底层都是用 ASM 实现的。

四、Btrace原理和应用

BTrace是SUN Kenai云计算开发平台下的一个开源项目,旨在为java提供安全可靠的动态跟踪分析工具。

那么,BTrace这么神奇的功能是如何实现的呢?既然这是个开源的代码,那么直接从代码找原理。BTrace代码开源在https://github.com/btraceio/btrace。

BTrace是基于动态字节码修改技术(Hotswap)来实现运行时java程序的跟踪和替换。大致的原理能够用下面的公式描述:

Client(Java compile api + attach api) + Agent(脚本解析引擎 + ASM + JDK6 Instumentation) + Socket

BTrace工做时序图以下:

BTrace就是使用ASM修改当前类,附加调试信息,获得新的类,通常状况下,Class文件是经过javac编译器产生的,而后经过类加载器加载到虚拟机内,再经过执行引擎去执行。如今能够经过ASM的API直接生成符合Java虚拟机规范的Class字节流,这样,ASM作的事情必定程度上正是javac解释器作的工做。

五、总结

字节码加强技术能够动态地对运行中的程序作修改,也能够跟踪JVM运行中程序的状态。此外,咱们平时使用的动态代理、AOP也与字节码加强密切相关,它们实质上仍是利用各类手段生成符合规范的字节码文件。

掌握字节码加强后能够高效地定位并快速修复一些棘手的问题(如线上性能问题、方法出现不可控的出入参须要紧急加日志等问题),也能够在开发中减小冗余代码,大大提升开发效率。

相关文章
相关标签/搜索