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

    文章

    682

    浏览量

    31089
  • 虚拟机
    +关注

    关注

    1

    文章

    968

    浏览量

    30176
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    时钟设计优化实战

    1、时钟设计,芯片性能的节拍器 在现代 IC 设计中,时钟网络的优化是实现高性能、高可靠性和低功耗的关键。本文聚焦四大核心技术:CTS 优化、DCD 最小化、时钟门控和时钟域交叉(CD
    的头像 发表于 10-09 10:07 289次阅读

    鸿蒙5开发宝藏案例分享---Grid性能优化案例

    发现鸿蒙宝藏:优化Grid组件性能的实战技巧! 大家好呀!最近在鸿蒙开发者社区挖到一个超实用的性能优化案例—— 解决Grid组件加载慢、滚动卡顿的问题 。官方其实藏了不少宝藏案例,但很
    发表于 06-12 17:47

    鸿蒙5开发宝藏案例分享---长列表性能优化解析

    鸿蒙长列表性能优化大揭秘!告别卡顿,实战代码解析来了! 大家好呀~今天在翻鸿蒙开发者文档时,发现了个 性能优化宝藏案例 !官方居然悄悄放出了长列表卡顿的完整解决方案,实测效果炸裂!我连
    发表于 06-12 17:40

    鸿蒙5开发宝藏案例分享---应用性能优化指南

    鸿蒙性能优化实战指南:让你的应用飞起来 ? 大家好!今天咱们聊聊鸿蒙(HarmonyOS)应用性能优化的实战技巧。结合官方文档和最佳实践,我整理了8大核心
    发表于 06-12 17:17

    鸿蒙5开发宝藏案例分享---性能优化案例解析

    鸿蒙性能优化宝藏指南:实战工具与代码案例解析 大家好呀!今天在翻鸿蒙开发者文档时,意外挖到一个 性能优化宝藏库 ——原来官方早就提供了超多实用工具和案例,但很多小伙伴可能没发现!这篇就
    发表于 06-12 16:36

    HarmonyOS优化应用内存占用问题性能优化

    应用开发过程中注重内存管理,积极采取措施来减少内存占用,以优化应用程序的性能和用户体验。 HarmonyOS提供了一些内存管理的工具和接口,帮助开发者有效地管理内存资源: onMemoryLevel接口
    发表于 05-21 11:27

    解决应用性能问题的策略

    性能调优贯穿于鸿蒙应用开发的整个生命周期中,开发前有性能最佳指南等赋能套件让你快速上手学习,开发过程中有性能工具开发套件覆盖应用开发各阶段,应用开发完成上架后有专业的性能测试工具检查测
    的头像 发表于 04-24 11:42 615次阅读
    解决<b class='flag-5'>应用性能</b>问题的策略

    HarmonyOS NEXT 原生应用/元服务-DevEco Profiler性能优化过程

    流程概览 在开发应用时,开发者会对应用的运行情况有一个预期的指标,当应用在某些方面不能满足预期的指标或者表现不佳时,意味着您的应用可能存在性能问题,需要对应用进行性能优化以达到您的预期。应用的
    发表于 02-19 15:28

    MPLS网络性能优化技巧

    MPLS(多协议标签交换)网络性能优化是一个复杂的过程,涉及多个方面的技术和策略。以下是一些关键的MPLS网络性能优化技巧: 一、确保网络设备支持 设备兼容性 :确保所有网络设备(如路
    的头像 发表于 02-14 17:09 1486次阅读

    前端性能优化:提升用户体验的关键策略

    在互联网飞速发展的今天,用户对于网页的加载速度和响应性能要求越来越高。前端性能优化成为了提升用户体验、增强网站竞争力的关键策略。一个性能良好的前端应用,能够快速响应用户的操作,减少等待
    的头像 发表于 01-22 10:08 848次阅读

    如何优化TCP协议的性能

    优化TCP协议的性能可以从多个方面入手,以下是一些关键的策略和方法: 一、调整TCP参数 TCP窗口大小 : 重要性 :TCP窗口大小是衡量TCP协议性能的一个关键参数,决定了无需等待确认应答即可
    的头像 发表于 01-22 09:52 1456次阅读

    如何优化总线系统的性能

    总线系统是计算机和其他电子设备中用于传输数据的关键组件。性能优化可以提高数据传输速率、降低延迟,并增强系统的可靠性和扩展性。 1. 理解总线系统 总线类型 :介绍不同类型的总线,如PCIe、USB
    的头像 发表于 12-31 09:54 1091次阅读

    华为云 X 实例 CPU 性能测试详解优化策略

    分析   3.2 CPU性能瓶颈分析   4. CPU性能优化策略   4.1 优化CPU性能的常用方法   4.2 操作系统内核调优  
    的头像 发表于 12-30 14:52 1182次阅读
    华为云 X 实例 CPU <b class='flag-5'>性能</b>测试<b class='flag-5'>详解</b>与<b class='flag-5'>优化</b>策略

    SSM框架的性能优化技巧 SSM框架中RESTful API的实现

    SSM框架的性能优化技巧 SSM(Spring + Spring MVC + MyBatis)框架的性能优化是提升Java Web应用性能
    的头像 发表于 12-17 09:10 1115次阅读

    提高网络性能的阻抗优化技巧

    提高网络性能的阻抗优化技巧涉及多个层面,包括电路板设计、网络架构设计、以及具体设备配置等。以下是一些关键的阻抗优化技巧,旨在提升网络的整体性能: 一、电路板设计层面的阻抗
    的头像 发表于 12-10 10:09 1302次阅读