0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

关于应用性能优化之VerifyClass详解

jf_f8pIz0xS 来源:掘金 作者:大力智能技术 2021-04-16 18:14 次阅读

为了加速应用冷启动过程且不过度涉及业务改动,本文从虚拟机加载类的过程中找到优化项,且与业界的方案作了对比,并实现了半自动化的分析功能。类在使用或实例化之前需要被加载到虚拟机中并进行初始化。整个过程如下图所示:主要由LoadingClass和InitializingClass两部分组合。

LoadingClass旨在把Class从Dex加载到虚拟机中,但不涉及类的使用或执行流程。InitializingClass旨在保证使用类前已经经过了初始化流程,此流程嵌入类的使用或执行过程中。

加载类

DefineClass主要通过SetupClass、InsertClass以及LoadClass将一个类加载到虚拟机中,最后返回mirror:Class对象指针。

SetupClass:设置类的访问标志以及ClassLoader。

InsertClass:将类插入到对应ClassLoader的ClassTable中,以便查找。

LoadClass:将类的属性及方法加载到类中。

类初始化

类的属性或方法在使用前必须经过类的初始化。

InitializeClass:核验类、初始化父类、接口方法以及静态属性。

VerifyClass:核验类的合法性,在下一节详细分析。

核验类

VerifyClass使用VerifyClassUsingOatFile或PerformClassVerification方法之一去核查Class。其中PerformClassVerification就包含了Systrace中耗时VerifyClass的Tag,如下图所示:

VerifyClassUsingOatFile:通过Oat文件中的Class状态位去核验Class,当状态位等于kStatusVerified时,核查流程到此为止,直接快速返回。否则需要进入耗时的PerformClassVerification流程。

PerformClassVerification:主要核验类中的直接方法和虚方法。

ComputeWidthsAndCountOps:判断PC值与dalvik指令数是否相等。

ScanTryCatchBlocks:检查Try语句开始地址、结束地址以及try开始操作符的合法性。检查catch中handler语句开始操作符的合法性。

VerifyInstructions:检查各种dalvik指令,同时将GC检查点插入到括号、switch、throw指令中。

VerifyCodeFlow:检查每条dalvik指令的寄存器以及参数的合法性。

提前发现

从上面的分析可以看出,应该尽可能让核查走VerifyClassUsingOatFile流程,即通过Oat文件状态位核查成功。Oat文件中类的状态位是什么以及为什么状态位不等于kStatusVerified是问题的突破点。

通过oatdump命令去dump相应的odex文件,可以查看类的状态位,操作方式如下:

VLOG默认是不会被打印的,需要动态开启,开启的方式可以通过:art::gLogVerbosity.class_linker = true而打开,因为本项目需要看到dex2oat和其他进程的打印情况,本人是在系统源码中进行编译生成的so,然后,通过ptrace注入so到Zygote的,此方法需要root设备,如果只需要查看本进程,应不需要这么麻烦,具体方法还未探索,但思路应该是一致的。举例如下,本人碰到的问题是AppCompat包中的类不能被核验通过。

解决方案

将Runtime对象中的verify_设置成verifier::VerifyMode::kNone。

需要通过Runtime对象首地址遍历查找verify_属性,魔改厂商可能带来兼容性问题。

缺少VerifyClass过程,可能会后置发现非法指令问题。

对zygote中值verify_进行修改将造成cow内存消耗。

将多出EnsureSkipAccessChecksMethods一步处理逻辑,将类中每个函数flag进行修改,此处逻辑没有对单个类进行处理,所以,每个类的每个函数的flag都将被无谓修改,如下图所示:

直面问题本身,通过VLOG的输出信息,去修正源码,具体到本案例,是由于AppCompat库中使用了系统不支持的语句,如下图所示:

本App运行环境是在8.1(API27)上,TextView没有方法setFirstBaselineToTopHeight,所以,因为指令非法导致类核验失败。(注意Build.VERSION.SDK_INT是不会被编译优化的,它本身是final类型,但它的取值是等于SystemProperties.getInt(“ro.build.version.sdk”, 0),所以,必须运行时,才能确定)。本人尝试了如下方法:

将系统源码sdk中的Build.VERSION.SDK_INT值设置成27进行编译出新的sdk,然后,将此sdk覆盖源生的android.jar,希望编译时将appcompat中的Build.VERSION.SDK_INT 》= 28判断逻辑优化掉,但实际aar不会参与sdk的编译,此项只能优化项目自身的逻辑。

将appcompat源码下载下来,去掉非法指令,重新编译成aar使用。

直接在android8.1源码中编译support v7包使用。

以上两种方法,能定制自己所需的aar,甚至能裁剪资源,但碰到了致命的问题:新生成的aar不能发布到maven了,这样的话,需要推动业务修改包名,另一个问题是,如果是项目中的第三方aar依赖了appcompat的话,问题又会出现。所以,最终通过制作ASM插件,将Build.VERSION.SDK_INT值设置成固定27,问题解决了,且使得本项目中apk size减少了22K。

如果是应用需要兼容多个不同版本的ROM,也可以按照ROM版本的不同,使用App Bundle下发“最合适”的App。

平台化

为了降低方案实施难度,现已将方案平台化,只要将apk拖入网页中即可看到类核验不通过的原因。
编辑:lyn

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 源码
    +关注

    关注

    8

    文章

    572

    浏览量

    28583
  • 虚拟机
    +关注

    关注

    1

    文章

    854

    浏览量

    27369
收藏 人收藏

    评论

    相关推荐

    HarmonyOS应用性能与功耗云测试

    性能测试 性能测试主要验证 HarmonyOS 应用在华为真机设备上运行的性能问题,包括启动时长、界面显示、CPU 占用和内存占用。具体性能测试项的详细说明请参考
    发表于 12-26 16:39

    .NET8极致性能优化AOT

    .NET8对于性能优化是方方面面的,所以AOT预编译机器码也是不例外的。本篇来看下对于AOT的优化
    的头像 发表于 12-06 10:16 385次阅读

    MySQL性能优化方法

    MySQL 性能优化是一项关键的任务,可以提高数据库的运行速度和效率。以下是一些优化方法,包括具体代码和详细优化方案。
    的头像 发表于 11-22 09:59 264次阅读

    CPU程序几个优化程序性能的手段详解

    要写出高性能的代码,首先需要对编译器有基础的了解,原因在于现代编译器有很强的优化能力,但有些代码编译器不能进行优化。对编译器有了基础的了解,才能写出编译器友好型高性能代码。
    的头像 发表于 11-21 09:46 254次阅读
    CPU程序几个<b class='flag-5'>优化</b>程序<b class='flag-5'>性能</b>的手段<b class='flag-5'>详解</b>

    GPRS的性能分析及优化

    电子发烧友网站提供《GPRS的性能分析及优化.pdf》资料免费下载
    发表于 11-17 16:31 0次下载
    GPRS的<b class='flag-5'>性能</b>分析及<b class='flag-5'>优化</b>

    使用Rust优化Python性能

    在数据分析领域Python无疑是最流行的编程语言,但是Python有一个硬伤就是作为一个编译语言在性能上有些微的欠缺。而同样最流行的语言Rust则在性能方面表现优秀。本文我们一起学习一个优化项目的实践,对一个数据分析程序,改为R
    的头像 发表于 11-01 15:59 464次阅读
    使用Rust<b class='flag-5'>优化</b>Python<b class='flag-5'>性能</b>

    【技术视界】鸿蒙开发套件DevEco Profiler助您轻松分析应用性能问题

    作者:shizhengtao,华为性能调优工具专家 应用的性能优化一直以来都是开发者所面临的一大难题,在2023HDC大会上全新亮相的HarmonyOS NEXT开发者预览版,其中鸿蒙开发
    发表于 09-15 15:55

    【技术视界】鸿蒙开发套件之DevEco Profiler助您轻松分析应用性能问题

    的是华为性能调优工具专家的分享,希望能为您的应用性能优化带来启发~ 作者:shizhengtao,华为性能调优工具专家 应用的性能
    的头像 发表于 09-15 12:15 440次阅读
    【技术视界】鸿蒙开发套件之DevEco Profiler助您轻松分析<b class='flag-5'>应用性能</b>问题

    使用STM32缓存来优化性能与功率效率

    下表中列出的 STM32 微控制器(MCU)中。这些缓存使用户从内部和外部存储器提取指令和数据时或在用于外部存储器的数据流量时提高应用性能并降低功耗。本文档提供了典型示例,以强调 ICACHE 和 DCACHE 功能,并便于配置。
    发表于 09-07 07:51

    使用32Gb/S光纤通道实现更快的应用性能

    电子发烧友网站提供《使用32Gb/S光纤通道实现更快的应用性能.pdf》资料免费下载
    发表于 08-29 11:00 0次下载
    使用32Gb/S光纤通道实现更快的<b class='flag-5'>应用性能</b>

    一文带你详解芯片--SL8541e-系统性能优化

    背景 伙伴反馈,设备操作卡顿,OH基础系统版本应用操作慢,应用人机交互体验差。本文为你总结芯片解决方案–SL8541e-系统性能优化。主要内容包括: *1. 确定优化思路 帧率优化
    发表于 08-22 09:12

    SpringCloud组件性能优化技巧分享

    Springcloud 原始的配置,性能是很低的,大家可以使用Jmeter测试一下,QPS不会到50。要做到高并发,需要做不少的配置优化
    的头像 发表于 08-16 09:47 633次阅读
    SpringCloud组件<b class='flag-5'>性能</b><b class='flag-5'>优化</b>技巧分享

    67 TraceView性能测试与Android应用性能优化方案 - 第1节67 TraceView性能测试与

    数据软件程序
    充八万
    发布于 :2023年07月29日 23:44:40

    如何提高数据仓库的性能优化设计

      随着数据仓库规模的扩大,数据仓库的性能问题就显得越来越突出,如何提高数据仓库的性能,除了在设计阶段对其逻辑结构和物理结构进行优化设计外;还可以在数据仓库运行阶段,采取一些优化措施来
    发表于 07-18 16:10 0次下载

    GaN功率集成电路:器件集成带来应用性能

    GaN功率半导体器件集成提供应用性能
    发表于 06-21 13:20