阅读本文前,建议先了解以下相关知识:

  1. JVM字节码
  2. java动态代理
  3. Java字节码插桩技术
  4. Java字节码操作框架ASM:史上最通俗易懂的ASM教程

Jacoco使用插桩的方式来记录覆盖率数据,是通过一个probe探针来注入。

一、覆盖率分析机制

有几种不同的方法来收集覆盖率信息。对于每种方法,由不同的实现技术,黄色路径是jacoco推荐的方式,即通过字节码插桩实现代码覆盖率的统计:

在ByteCode字节码上插桩模式有两种:

1. on-the-fly模式

JVM通过 -javaagent参数指定jar文件启动代理程序,代理程序在ClassLoader装载一个class前判断是否修改class文件,并将探针插入class文件,探针不改变原有方法的行为,只是记录是否已经执行。

2. offline模式

在测试之前先对文件进行插桩,生成插过桩的class或jar包,测试插过桩的class和jar包,生成覆盖率信息到文件,最后统一处理,生成报告。

二、jacoco插桩策略

参考文章:Java方法的控制流分析

1、Java字节码的控制流程图

要实现对代码的覆盖率统计,首先要了解方法的内部控制流。以下面这段java代码为例

public static void example() {a();if (cond()) {b();} else {c();}d();
}

编译之后的字节码如下(.class文件中保存的就是字节码):

public static example()VINVOKESTATIC a()VINVOKESTATIC cond()ZIFEQ L1INVOKESTATIC b()VGOTO L2L1: INVOKESTATIC c()VL2: INVOKESTATIC d()VRETURN

控制流通过有条件或无条件操作码之类的跳转指令 来实现。跳转目标在技术上是相对于目标指令的相对偏移。为了提高可读性,我们改用符号标签(ASM API也使用此类符号标签,IFEQ L1 GOTO L2):

上面字节码的控制流程可以用流程图表示。节点是字节码指令,边表示指令之间的控制流。该示例的控制流显示在该图的左框中:

2、探针插入策略

探针就是可以插入现有指令之间的一段其他指令,它们不会改变方法的行为,但是会记录它们已被执行的事实。

jacoco插桩并不是每行,探针实现本身需要多个字节码指令,因此这将使类文件的大小增加数倍,并显着降低所检测类的执行速度。实际上,根据方法的控制流程,每个方法仅需要几个探针,具体策略如下:

  • 在每个方法出口处(返回或抛出)插入探针
  • 具有多条指向边的目标指令的多条指向边上

二、jacoco原理

Jacoco on-the-fly 模式通过jacoco agent在类加载时对原始类进行插桩,得到插桩后的类。正常class文件加载流程如下:

被jacoco代理的class文件加载流程

jacoco底层原理解析相关推荐

  1. java aqs详解_Java AQS底层原理解析

    AQS底层原理 AQS(AbstractQueuedSynchronizer)是一个抽象同步队列,JUC(java.util.concurrent)中很多同步锁都是基于AQS实现的. AQS的基本原理 ...

  2. Https丢包分析及底层原理解析

    一.背景 生产服务器为阿里云,应用系统出现请求第三方服务偶发性接口异常,数据查询不回来,查看日志,分析得出,请求接口超过最大连接时间30秒,正常1.2秒左右,能返回数据.经过确认,第三方https连接 ...

  3. dubbo底层原理解析及安装应用

    0.dubbo安装 1.dubbo简介 2-0.Dubbo标签 2-1.xml方式配置dubbo 2-2.注解方式配置dubbo 2-3.Api方式配置Dubbo 2-4.springboot方式配置 ...

  4. AOP—JVM SandBox—底层原理解析

    原文作者:陆晨 原文地址:JVM SandBox 的技术原理与应用分析 目录 一.前言 二.JVM SandBox 简介 2.1 AOP 2.2 JVM SandBox 三.JVM 核心技术 3.1 ...

  5. Unity 协程底层原理解析

    1.协程 unity是单线程设计的游戏引擎,unity实际上有多条渲染线程,但对于unity调用我们编写的游戏脚本,都是放在一个主线程当中进行调度的.因此对于我们写的游戏脚本unity是单线程的. 协 ...

  6. 分布式事务之底层原理揭秘

    , hi 大家好,今天分享一这篇文章,让大家彻底了解分布式原理,这个是后台开发必须掌握技能. 刚性事务 柔性事务 本地事务 分布式事务 单阶段原子提交协议 两阶段提交协议 定义 原理 性能 恢复 缺陷 ...

  7. HashMap底层原理(当你put,get时内部会发生什么呢?)

    HashMap底层原理解析(一) 接触过HashMap的小伙伴都会经常使用put和get这些方法,那接下来就对HashMap的内部存储进行详解.(以初学者的角度进行分析)-(小白篇) 当程序试图将多个 ...

  8. 19.Atomic系列之LongAdder的底层原理(分段锁提升并发性能)

    老王:小陈啊,上一章我们讲解了cas的缺陷,无法同时更新多个变量.以及ABA的问题.以及如果使用AtomicReference解决同时更新多个变量,如果使用AtomicStampedReference ...

  9. 18.AtomicReference、AtomicStampReference底层原理。多个变量更新怎么保证原子性?CAS的ABA问题怎么解决?

    老王:小陈啊,上一章我们说了AtomicInteger.AtomicBoolean的底层原理,这一篇我们就来说说Atomic系列的另一个分类AtomicReference和AtomicStampRef ...

最新文章

  1. linux nfs建立共享目录,linux下nfs磁盘共享目录
  2. 深入解析C++编程中的静态成员函数
  3. [设计模式] javascript 之 策略模式
  4. python keyboard库_python利用 keyboard 库记录键盘事件
  5. shell类型、添加PATH环境变量、.bashrc、.profile、/etc/profile、/etc/environment
  6. Flink API之Source入门
  7. openmv探索_2_追踪单颜色
  8. 设计模式 (十八 ) 观察者模式
  9. 用友t 的服务器找不到系统管理,用友T+找不到账套了怎么办
  10. Ubuntu破解密码
  11. 分享刚学会的安装手机浏览器的实用插件tampermonkey方法
  12. Cisco路由器密码设置
  13. ANC主动降噪技术的原理
  14. window远程桌面无法复制粘贴文件到本地
  15. MySQL数据库维护手册
  16. 物联网案例研究:确保格兰仕智能设备不易受黑客攻击
  17. BM46 最小的K个数
  18. python字母转换_python中字母与ascii码的相互转换
  19. 画直方图(hist)
  20. 设计模式(四)责任链模式——责任链模式结构

热门文章

  1. Swift 泛型參数
  2. 如何设置SecureCRT通过代理连接SSH[转]
  3. Remoting简介
  4. pipenv 虚拟环境新玩法
  5. PHP 算法之 -- 计算器设计
  6. Centos6 安装RabbitMq3.7.7
  7. 1.void main
  8. Mybatis接口注解开发
  9. form表单按enter键自动提交的问题
  10. SH1B LMR62014XMFE/NOPB