jacoco底层原理解析
阅读本文前,建议先了解以下相关知识:
- JVM字节码
- java动态代理
- Java字节码插桩技术
- 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底层原理解析相关推荐
- java aqs详解_Java AQS底层原理解析
AQS底层原理 AQS(AbstractQueuedSynchronizer)是一个抽象同步队列,JUC(java.util.concurrent)中很多同步锁都是基于AQS实现的. AQS的基本原理 ...
- Https丢包分析及底层原理解析
一.背景 生产服务器为阿里云,应用系统出现请求第三方服务偶发性接口异常,数据查询不回来,查看日志,分析得出,请求接口超过最大连接时间30秒,正常1.2秒左右,能返回数据.经过确认,第三方https连接 ...
- dubbo底层原理解析及安装应用
0.dubbo安装 1.dubbo简介 2-0.Dubbo标签 2-1.xml方式配置dubbo 2-2.注解方式配置dubbo 2-3.Api方式配置Dubbo 2-4.springboot方式配置 ...
- AOP—JVM SandBox—底层原理解析
原文作者:陆晨 原文地址:JVM SandBox 的技术原理与应用分析 目录 一.前言 二.JVM SandBox 简介 2.1 AOP 2.2 JVM SandBox 三.JVM 核心技术 3.1 ...
- Unity 协程底层原理解析
1.协程 unity是单线程设计的游戏引擎,unity实际上有多条渲染线程,但对于unity调用我们编写的游戏脚本,都是放在一个主线程当中进行调度的.因此对于我们写的游戏脚本unity是单线程的. 协 ...
- 分布式事务之底层原理揭秘
, hi 大家好,今天分享一这篇文章,让大家彻底了解分布式原理,这个是后台开发必须掌握技能. 刚性事务 柔性事务 本地事务 分布式事务 单阶段原子提交协议 两阶段提交协议 定义 原理 性能 恢复 缺陷 ...
- HashMap底层原理(当你put,get时内部会发生什么呢?)
HashMap底层原理解析(一) 接触过HashMap的小伙伴都会经常使用put和get这些方法,那接下来就对HashMap的内部存储进行详解.(以初学者的角度进行分析)-(小白篇) 当程序试图将多个 ...
- 19.Atomic系列之LongAdder的底层原理(分段锁提升并发性能)
老王:小陈啊,上一章我们讲解了cas的缺陷,无法同时更新多个变量.以及ABA的问题.以及如果使用AtomicReference解决同时更新多个变量,如果使用AtomicStampedReference ...
- 18.AtomicReference、AtomicStampReference底层原理。多个变量更新怎么保证原子性?CAS的ABA问题怎么解决?
老王:小陈啊,上一章我们说了AtomicInteger.AtomicBoolean的底层原理,这一篇我们就来说说Atomic系列的另一个分类AtomicReference和AtomicStampRef ...
最新文章
- linux nfs建立共享目录,linux下nfs磁盘共享目录
- 深入解析C++编程中的静态成员函数
- [设计模式] javascript 之 策略模式
- python keyboard库_python利用 keyboard 库记录键盘事件
- shell类型、添加PATH环境变量、.bashrc、.profile、/etc/profile、/etc/environment
- Flink API之Source入门
- openmv探索_2_追踪单颜色
- 设计模式 (十八 ) 观察者模式
- 用友t 的服务器找不到系统管理,用友T+找不到账套了怎么办
- Ubuntu破解密码
- 分享刚学会的安装手机浏览器的实用插件tampermonkey方法
- Cisco路由器密码设置
- ANC主动降噪技术的原理
- window远程桌面无法复制粘贴文件到本地
- MySQL数据库维护手册
- 物联网案例研究:确保格兰仕智能设备不易受黑客攻击
- BM46 最小的K个数
- python字母转换_python中字母与ascii码的相互转换
- 画直方图(hist)
- 设计模式(四)责任链模式——责任链模式结构