Jacoco实现原理

4 篇文章 1 订阅

两分钟全面了解Jacoco

覆盖率分析机制
覆盖率信息必须在运行时收集,Jacoco on-the-fly 模式通过jacoco agent在类加载时对原始类进行插桩,得到插桩后的类。
收集覆盖率信息有几种方法,没有方法有几种不同的实现机制,橙色部分为Jacoco on-the-fly收集方式
覆盖率收集方法

Java代码覆盖率实现方式有哪些

字节码插桩非常快,通过纯java实现,并且可以在任意java 虚拟机上运行。On-the-fly插桩模式通过为java虚拟机添加Java agent hook实现,不用改变目标应用程序。
Java agent hook需要Jvm 1.5版本以上,对于包含debug信息的编译代码,可以对源码行高亮展示,但是字节码中包含的一些构造函数无法被高亮,比如默认构造函数,finally控制流。
Jacoco Agent 独立于应用程序
Jacoco agent 被应用程序类加载器加载,所以Jacoco agent的类和应用程序的类共存于同一类空间中,这样就可能发生类冲突,尤其对第三方库ASM,所以Jacoco的构建设计把agent的所有类都移到唯一的包中。
jacocoagent.jar中所有的类构建后会被移动到前缀为org.jacoco.agent.rt_的包中,包括依赖的ASM库,标识符是一个随机数,Jacoco agent没有提供api去定制标识符的值,这样Jacoco的测试也可以通过Jacoco来验证。
字节码改写
Jacoco通过ASM库,对字节码进行改写来完成插桩。ASM是轻量、简单易用、高效。
Java类标识符
Jacoco通过对原始类的CRC64 哈希码作为类标识符,来对类的覆盖率数据进行聚合。
在有多个类加载器时,类名称不能明确识别一个类,比如OSGI允许同一个加载器加载不同版本的类,在覆盖的部署场景,可能测试的版本并不是部署的版本,Jacoco必须保证得到的覆盖率报告来自从有效的被测对象,类定义的哈希码可以区分类的不同版本,CRC64可以简单、快速的产生一个64位的哈希码。
运行依赖
插桩后的数据需要在运行时收集并产生覆盖率数据,在使用自己的类加载机制的框架中,使运行库对所有插入指令的类都可用可能是一项痛苦或不可能完成的任务。从Java 1.6开始java.lang.instrument.Instrumentation有一个API来扩展bootsstrap加载程序,JaCoCo仅通过官方的JREAPI类型将插入指令的类和运行时覆盖数据解耦。插入指令的类通过对象.等于(对象)方法识别运行时的类。插入指令的类可以使用以下代码检索其探针。请注意,这里仅使用JRE API:

Object access = ...                          // Retrieve instance

Object[] args = new Object[3];
args[0] = Long.valueOf(8060044182221863588); // class id
args[1] = "com/example/MyClass";             // class name
args[2] = Integer.valueOf(24);               // probe count

access.equals(args);

boolean[] probes = (boolean[]) args[0];

内存占用
对于大型项目(有几千个类,百万行代码)的分析都是可以的,为了减少内存消耗,采用深度优先的遍历方法。
对于合理的堆内存占用,大的覆盖率报告树太大了,所以覆盖率的分析和报告的生成采用深度优先遍历,这样在任何一个节点内存中只会保留以下信息:

  1. 正在被处理的类
  2. 这个类的父类(包,组)的情况

Java元素标识符
Java语言和JavaVM对Java元素使用不同的字符串表示格式。例如,Java中的类型用java.lang.Object,VM中用Ljava/lang/Object;相同的类型;jacocoapi仅基于VM标识符。
直接使用VM标识符不会在运行时造成任何转换开销。有几种基于Jvm的编程语言可能使用不同的符号。因此,特定的转换应该只在用户层发生,例如在生成报告期间。
Jacoco实现模块化
JaCoCo实现了几个提供不同功能的模块,这些模块以OSGi捆绑包的形式提供,并带有适当的清单文件,但Jacoco本身没有依赖OSGI。
在OSGi容器中使用OSGI捆绑包可以在开发和运行时定义良好的依赖关系。由于Jacoco对OSGi没有依赖关系,因此捆绑包也可以像普通JAR文件一样使用。

更多精彩内容,欢迎关注B站账号
在这里插入图片描述

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值