CN109426546B - 应用启动方法及装置、计算机存储介质及设备 - Google Patents
应用启动方法及装置、计算机存储介质及设备 Download PDFInfo
- Publication number
- CN109426546B CN109426546B CN201710780649.3A CN201710780649A CN109426546B CN 109426546 B CN109426546 B CN 109426546B CN 201710780649 A CN201710780649 A CN 201710780649A CN 109426546 B CN109426546 B CN 109426546B
- Authority
- CN
- China
- Prior art keywords
- address
- virtual machine
- class
- value
- pointed
- Prior art date
- Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
- Active
Links
Images
Classifications
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F9/00—Arrangements for program control, e.g. control units
- G06F9/06—Arrangements for program control, e.g. control units using stored programs, i.e. using an internal store of processing equipment to receive or retain programs
- G06F9/44—Arrangements for executing specific programs
- G06F9/455—Emulation; Interpretation; Software simulation, e.g. virtualisation or emulation of application or operating system execution engines
- G06F9/45533—Hypervisors; Virtual machine monitors
- G06F9/45558—Hypervisor-specific management and integration aspects
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F9/00—Arrangements for program control, e.g. control units
- G06F9/06—Arrangements for program control, e.g. control units using stored programs, i.e. using an internal store of processing equipment to receive or retain programs
- G06F9/44—Arrangements for executing specific programs
- G06F9/445—Program loading or initiating
- G06F9/44505—Configuring for program initiating, e.g. using registry, configuration files
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F9/00—Arrangements for program control, e.g. control units
- G06F9/06—Arrangements for program control, e.g. control units using stored programs, i.e. using an internal store of processing equipment to receive or retain programs
- G06F9/44—Arrangements for executing specific programs
- G06F9/455—Emulation; Interpretation; Software simulation, e.g. virtualisation or emulation of application or operating system execution engines
- G06F9/45533—Hypervisors; Virtual machine monitors
- G06F9/45558—Hypervisor-specific management and integration aspects
- G06F2009/45575—Starting, stopping, suspending or resuming virtual machine instances
Abstract
一种应用启动方法及装置、计算机存储介质及设备,该方法包括:获取应用启动指令;查找应用启动指令所对应的虚拟机实例的地址;按虚拟机实例的地址,查找虚拟机实例中类验证模式字段的地址;将类验证模式字段的地址所指向的值,修改为用于在加载类时跳过类验证的值;调用类加载函数,通过类加载函数并根据类验证模式字段的地址所指向的值,加载应用启动指令所对应的类。基于本申请所提供的实施例的方案,可提高类加载速度,从而提高应用启动速度,可减少对业务逻辑使用的影响。
Description
技术领域
本发明涉及计算机信息处理技术领域,特别涉及一种应用启动方法及装置、计算机存储介质及设备。
背景技术
随着移动互联网的发展,Android(安卓)应用市场竞争愈发激烈。应用开发者不仅要不断开发新功能满足用户需求,还要不断提升应用的性能以便为用户提供更好的体验,其中,应用启动速度为应用的一个重要性能指标。
对于大型Android应用,其业务逻辑多,启动时需要执行的逻辑多,加大了优化启动速度的难度。目前,应用开发者提出的优化应用启动的方案主要通过业务逻辑延迟加载,以减少启动过程中CPU(中央处理器)以及IO(输入输出)等系统资源竞争,加快启动相关逻辑的执行。
然而,目前提升Android应用的启动速度的方案,需要将部分业务逻辑延迟启动来提高应用的启动速度,而延迟启动的部分业务逻辑实际上没有加速启动或者启动更慢,导致延迟启动的部分业务逻辑的使用受到影响。
发明内容
基于此,有必要针对目前应用启动加速影响导致业务逻辑使用受到影响的问题,提出一种应用启动方法及装置、计算机存储介质及设备。
据此,本实施例采用以下技术方案:
一种应用启动方法,应用于终端,包括以下步骤:
获取应用启动指令;
查找所述应用启动指令所对应的虚拟机实例的地址;
按所述虚拟机实例的地址,查找所述虚拟机实例中类验证模式字段的地址;
将所述类验证模式字段的地址所指向的值,修改为用于在加载类时跳过类验证的值;
调用类加载函数,通过所述类加载函数并根据所述类验证模式字段的地址所指向的值,加载所述应用启动指令所对应的类。
一种应用启动装置,应用于终端,包括:
指令获取模块,用于获取应用启动指令;
第一地址查找模块,用于查找所述应用启动指令所对应的虚拟机实例的地址;
第二地址查找模块,用于按所述虚拟机实例的地址,查找所述虚拟机实例中类验证模式字段的地址;
修改模块,用于将所述类验证模式字段的地址所指向的值,修改为用于在加载类时跳过类验证的值;
加载模块,用于调用类加载函数,通过所述类加载函数并根据所述类验证模式字段的地址所指向的值,加载所述应用启动指令所对应的类。
一种计算机存储介质,其上存储有计算机程序,该计算机程序被处理器执行时实现上述任意一项所述方法的步骤。
一种计算机设备,包括存储器、处理器以及存储在所述存储器上并可在所述处理器上运行的计算机程序,所述处理器执行所述计算机程序时上述任意一项所述的方法。
通过上述应用启动方法及装置、计算机存储介质以及设备,获取到应用启动指令,表示需要对应用进行启动,然后查找应用启动指令所对应的虚拟机实例的地址,根据虚拟机实例的地址,可查找到虚拟机实例中类验证模式字段的地址,将类验证模式字段的地址所指向的值修改为用于在加载类时跳过类验证的值,如此,在应用启动过程中,根据类加载函数以及类验证模式字段的地址所指向的值加载类时,无需对类进行验证,即跳过类验证过程,节省大量时间,提升类加载速度,从而提升应用整体的启动速度,可减少对业务逻辑使用的影响。
附图说明
图1为本发明一个实施例的工作环境示意图;
图2为一个实施例中的终端的组成结构示意图;
图3为一个实施例的应用启动方法的流程示意图;
图4为另一个实施例的应用启动方法的子流程示意图;
图5为另一个实施例的应用启动方法的子流程示意图;
图6为现有首次加载Dex流程图;
图7为现有应用启动过程中类加载的流程图;
图8为一具体实施例的应用启动装方法的流程图;
图9为一个实施例的应用启动装置的模块示意图;
图10为另一个实施例的应用启动装置的子模块示意图;
图11为另一个实施例的应用启动装置的子模块示意图。
具体实施方式
为使本发明的目的、技术方案及优点更加清楚明白,以下结合附图及实施例,对本发明进行进一步的详细说明。应当理解,此处所描述的具体实施方式仅仅用以解释本发明,并不限定本发明的保护范围。
图1示出了本发明一个实施例中的工作环境示意图,如图1所示,其工作环境涉及终端10和服务器20,终端10和服务器20通过网络30连接,终端10及服务器20可以通过网络30进行通信。终端10在获取到应用启动指令后,响应于应用启动指令,可对虚拟机对象中的类验证模式字段的地址所指向的值进行修改,修改为用于在加载类时跳过类验证的值,根据类加载函数以及类验证模式字段的地址所指向的值加载应用启动指令所对应的类,实现对类的加载。如此,在进行类加载时,可跳过类验证,减少加载时间,提高类加载速度,从而加快启动应用速度。应用启动后可通过终端10与服务器20进行信息传递,即应用启动后,可在需要与服务器20交互时进行交互,例如,可通过终端10向服务器20发送数据请求,服务器20响应数据请求返回数据请求对应的数据至终端10,实现两者之间的数据通信。该终端10可以是任何一种能够实现智能输入输出以及启动应用的设备,例如,台式电脑或移动终端,移动终端可以是智能手机、平板电脑、车载电脑、穿戴式智能设备等。该服务器20可以是接收终端10发送的数据请求并返回数据的平台所在的服务器;服务器20可以为一个或多个。本实施例涉及的是终端10进行应用启动优化的方案。
终端10在一个实施例中的内部结构图如图2所示。该终端10包括通过系统总线连接的处理器、存储介质、网络接口和内存。其中,终端10的存储介质存储有操作系统和计算机可读指令,该计算机刻度指令在被处理器执行时,可使得处理器实现一种应用启动方法。终端10的处理器用于提供计算和控制能力,支撑整个终端10的运行。终端10的内存中可储存有计算机可读指令,该计算机可读指令被处理器执行时,可使得处理器执行一种应用启动方法。终端10的网络接口用于与网络30连接和通信。
请参阅图3,一个实施例中的应用启动方法,应用于终端,包括以下步骤S310至步骤S350:
S310:获取应用启动指令。
终端上可安装多种多样的应用,通过终端可启动应用实现对应用的智能操作。终端在获取到应用启动指令时,表示需要对应用启动指令对应的应用进行启动,后续会响应该应用启动指令执行相应的动作。
在一个实施例中,终端可显示应用图标,检测到对应用图标的操作时获取到用于启动该应用图标所对应应用的应用启动指令。
例如,终端上安装有A应用并在终端桌面上显示A应用图标,用户可对A应用图标进行点击操作,终端在检测到该点击操作响应该点击操作可获取到对A应用的应用启动指令。
又例如,终端上安装有B应用,但终端上不显示B应用图标,可通过在终端上的应用程序管理中查找到B应用,然后进行开启操作,终端响应开启操作可获取到对B应用的应用启动指令。
S320:查找应用启动指令所对应的虚拟机实例的地址。
虚拟机在计算机科学中的体系结构里,是指一种特殊的程序,它可以在计算机平台和终端用户之间创建一种环境,而终端用户则是基于这个软件所创建的环境来操作软件。可以理解,虚拟机是指可以像真实机器一样运行程序的计算机程序。在启动应用过程中,接收到应用启动指令后,系统会启动一个应用进程,在该应用进程中启动应用对应的虚拟机实例,也就是会对虚拟机进行实例化,虚拟机实例即为对虚拟机实例化后得到具体对象,对象是具体的,占用存储空间,即在接收到应用启动指令后,会对虚拟机进行实例化得到虚拟机实例并进行存储,虚拟机实例有其对应的地址,查找应用启动指令所对应的虚拟机对象的地址即可。
具体地,启动一个应用需要实例化一次虚拟机,每个应用启动各自对应一个虚拟机实例,例如,在终端中安装有A应用和B应用,启动A应用的过程中,需要实例化一个与之对应的虚拟机实例,若还需要启动B应用,在启动B应用过程中,需要实例化一个与之对应的虚拟机实例。
S330:按虚拟机实例的地址,查找虚拟机实例中类验证模式字段的地址。
虚拟机实例中包括有各字段(可以理解为变量),即在虚拟机实例中定义了各种字段,每个字段对应有地址,可在地址中查找对应字段的值。
在本实施例中,虚拟机实例中包括了类验证模式字段,虚拟机实例在启动时配置类验证模式字段的值为默认值,该默认值是会触发类验证的,于是在类验证模式字段的值为默认值的情况下,需要进行类验证,耗费大量时间。为了节省类加载时间提高加载速度,需要对类验证模式字段的地址指向的值进行修改,则需要先查找到虚拟机实例中类验证模式字段的地址。
S340:将类验证模式字段的地址所指向的值,修改为用于在加载类时跳过类验证的值。
在查找到虚拟机实例中类验证模式字段的地址后,通过类验证模式字段的地址可查找到类验证模式字段的地址所指向的值,然后可进行值修改动作,即可将类验证模式字段的地址所指向的值,修改为用于在加载类时跳过类验证的值。如上,类验证模式字段的值为默认值时表示在加载类时需要进行类校验,比较耗时,为了节省加载时间,将类验证模式字段的地址所指向的值,修改为用于在加载类时跳过类验证的值后,在进行类加载的过程中,无需再进行类验证过程。例如,默认值为3,用于在加载类时跳过类验证的值为1,当虚拟机实例中类验证模式字段的地址所指向的值为默认值3时,表示在加载类过程中需要进行类验证,将类验证模式字段的地址所指向的值修改为加载类时跳过类验证的值1后,由于1表征加载类时跳过类验证的值,可跳过类验证过程,加快加载速度。
S350:调用类加载函数,通过类加载函数并根据类验证模式字段的地址所指向的值,加载应用启动指令所对应的类。
当类验证模式字段的地址所指向的值为用于在加载类时跳过类验证的值时,在调用类加载函数,通过类加载函数并根据类验证模式字段的地址所指向的值进行类加载过程,可以认为类已被校验过,无需再验证,即会跳过类验证,加快加载速度。由于不同应用在启动时所需加载的类可能也不同,而根据应用启动指令可知对应需要启动的应用,从而根据应用启动指令可获取对应的应用启动时所需的类,即应用启动指令所对应的类,则在加载过程中,加载应用启动指令所对应的类也就加载了应用启动所需的类。
例如,每个应用有其对应的类,不同的应用功能可对应不同的类,不同应用可对应不同启动时所需类,比如,启动A应用需要加载10个类,则在启动A应用时需要加载这10个类,启动引用B需要加载15个类,则在启动B应用时需要加载这15个类。
通过上述应用启动方法,获取到应用启动指令,表示需要对应用进行启动,然后查找应用启动指令所对应的虚拟机实例的地址,根据虚拟机实例的地址,可查找到虚拟机实例中类验证模式字段的地址,将类验证模式字段的地址所指向的值修改为用于在加载类时跳过类验证的值,如此,在应用启动过程中,根据类加载函数以及类验证模式字段的地址所指向的值加载类时,无需对类进行验证,即跳过类验证过程,节省大量时间,提升类加载速度,从而提升应用整体的启动速度,可减少对业务逻辑使用的影响。
请参阅图4,在其中一个实施例中,上述按虚拟机实例的地址,查找虚拟机实例中类验证模式字段的地址的步骤S330包括:
S431:按虚拟机实例的地址,查找虚拟机实例中指向预设固定值的预设字段的地址。
在虚拟实例中包括预设字段,该预设字段的地址所指向的值为预设固定值,在查找到虚拟机实施例的地址后,可查找到虚拟机实例的地址所对应的虚拟机实例中指向预设固定值的预设字段的地址,由于预设固定值表示预先设定的能唯一确定预设字段地址的值,即根据预设固定值可准确找到唯一的预设字段的地址,提高地址查找的准确性。
例如,预设固定值可为/data/anr/traces.txt字符串,该字符串在虚拟机实例源码上为stackTraceFile指针指向的值,即stackTraceFile为指向/data/anr/traces.txt字符串的指针,通过stackTraceFile指针指向地址所指向的值是比较不常见的,也就不容易产生重复,将stackTraceFile指针作为预设字段,指针stackTraceFile指向的地址即为预设字段的地址,则预设字段的地址指向的值不容易产生重复,从而减少由于重复导致查找的预设字段的地址不准确问题,如此,可准确查找到虚拟机实例中指向/data/anr/traces.txt字符串的stackTraceFile指针指向的地址,即可准确找到预设字段的地址。
S432:根据预设字段的地址,以及预设字段与类验证模式字段的相对位置关系,确定类验证模式字段的地址。
在虚拟机实例中每个字段间预先就有相对位置关系,具体为地址的相对位置关系,在预设字段的地址确定后,由于预设字段的地址的准确性得以保证,根据预设字段的地址,以及预设字段与类验证模式字段的相对位置关系,确定类验证模式字段的地址,可确保类验证模式字段的地址的准确性。
请参阅图5,在其中一个实施例中,上述按虚拟机实例的地址,查找虚拟机实例中指向预设固定值的预设字段的地址的步骤S431包括以下步骤S531-S535:
S531:初始化临时指针,临时指针指向虚拟机实例的地址。
S532:将临时指针加1。
获取到虚拟机实例的地址后,需要查找虚拟机实例中指向预设固定值的预设字段的地址,虚拟机实例中第一行中字段的地址与虚拟机实例的地址是相同的,即第一行中字段的指针指向的地址与虚拟机实例的地址是相同的,相邻两行字段的地址是连续的,通过逐行查找的方式进行预设字段的地址的查找,从而需要初始化一个临时指针,该临时指针指向虚拟机实例的地址,单次对临时指针增加1可实现逐行查找,第一次进行查找时,临时指针加1后指向的虚拟机实例中第二行中字段的地址,后续依次往虚拟机实例中地址增大方向增加,直到找到指向的地址所指向的值与预设固定值相同。
S533:读取临时指针指向的地址所指向的值。
指针指向的是地址,地址指向的是值,临时指针加1后开始进行值读取,即读取临时指针指向的地址所指向的值,是为后续检测临时指针指向的地址所指向的值与预设固定值的状态作准备。
S534:当临时指针指向的地址所指向的值与预设固定值不同时,返回将临时指针增加1的步骤。
由于预设字段的地址指向的值为预设固定值,当临时指针指向的地址所指向的值与预设固定值不同时,表示还未找到预设字段的地址,此时需要继续往虚拟机实例中地址增加的方向查找,即返回将临时指针增加1的步骤继续查找。
S535:当临时指针指向的地址所指向的值与预设固定值相同时,将临时指针指向的地址作为预设字段的地址。
当临时指针指向的地址所指向的值与预设固定值相同时,预设固定值可以认为是虚拟机实例中预设字段地址唯一能指向的值,由于值相同,可以认为临时指针指向的地址即为预设字段的地址,临时指针指向的地址作为预设字段的地址,预设字段的地址查找成功。
在本实施例中,上述读取临时指针指向的地址所指向的值的步骤之前,还包括步骤:获取可读地址列表,当临时指针指向的地址为可读地址列表中的可读地址时,进入读取临时指针指向的地址所指向的值的步骤。
具体地,在地址信息记录文件中存储有可读地址列表、不可读地址列表、可写地址列表以及不可写地址列表,为了避免在查找过程中出现地址不可读报错的情况,增加查找时间的问题,进行地址可读性检测,在临时指针指向的地址为可读地址列表中的可读地址时,表示临时指针指向的地址可读,此时,可读取临时指针指向的地址所指向的值。
在其中一个实施例中,将临时指针加1的步骤之后还包括:记录临时指针增加的次数。
当临时指针指向的地址所指向的值与预设固定值不相同,且增加的次数小于预设次数时,返回将临时指针增加1的步骤;
当临时指针指向的地址所指向的值与预设固定值不相同,且增加的次数达到预设次数时,停止对预设字段的地址的查找。
在本实施例中,不仅需要检测临时指针指向的地址所指向的值与预设固定值之间的关系,还增加了检测指针增加的次数与预设次数之间的关系。
当检测到临时指针指向的地址所指向的值与预设固定值不相同时,表示还未找到预设字段的地址,此处,还需检测增加的次数与预设次数之间的大小关系,当增加的次数小于预设次数时,表示没有超出检测的范围,还可返回将临时指针增加1的步骤继续,若增加的次数达到了预设次数,相当于在没有找到预设字段的地址的情况下指针增加的次数以达到上限,即超出了超找的范围,此时停止对预设字段的地址的查找,由于对预设字段的地址的查找为修改类验证模式字段的地址所指向的值中的子步骤,停止对预设字段的地址的查找,也就停止了对类验证模式字段的地址所指向的值的修改。
例如,虚拟机实例中字段占用的地址总长度一般情况下不会超过400,通过临时指针的不断增加,且临时指针是从第二行中的字段的地址开始查找的,增加1次则到达第三行的字段的地址开始查找,当增加的次数达到400时,表示到达了第401行的字段的地址查找,然而这时超出了400,此时,停止对预设字段的地址的查找,从而停止了类验证字段的地址所指向的值的修改,后续还可进行类加载以启动应用。
在其中一个实施例中,将类验证模式字段的地址所指向的值,修改为用于在加载类时跳过类验证的值的步骤包括:当类验证模式字段的地址所指向的值为默认值时,将类验证模式字段的地址所指向的值修改为用于在加载类时跳过类验证的值。
其中,默认值在虚拟机实例启动时配置且用于触发类验证。
由于在开启虚拟机实例时会配置类验证模式的值为一个默认值,以表示在进行类加载时需要进行类验证过程,当类验证模式字段的地址所指向的值不为默认值时,可能对虚拟机实例中的字段进行了修改,例如在预设字段与类验证模式字段之间插入了一个字段,则预设字段与类验证模式字段之间的相对位置关系是变了,则上述根据预设字段的地址和相对位置关系确定的类验证模式字段的地址存在错误,此时根据预设字段的地址和相对位置关系确定的地址应是插入的字段的地址,考虑到虚拟机实例中的字段的严谨和确保运行的顺畅,不进行字段的值的修改。当类验证模式字段的地址所指向的值为默认值时,即类验证模式字段的地址所指向的值为虚拟机实例启动时配置的且会触发类验证的默认值,此时,可将类验证模式字段的地址所指向的值修改为用于在加载类时跳过类验证的值,以加快后续类加载的速度。
在其中一个实施例中,查找应用启动指令所对应的虚拟机实例的地址的步骤包括:调用文件打开函数打开虚拟机核心动态库,获得虚拟机核心动态库的句柄;调用地址获取函数并根据虚拟机核心动态库的句柄,在虚拟机核心动态库中,查找应用启动指令所对应的虚拟机实例的地址。
可以理解,虚拟机实例时存在一个虚拟机核心动态库中,为了顺利从虚拟机核心动态库中找到虚拟机实例的地址,首先需要调用文件打开函数打开虚拟机核心动态库,获得虚拟机核心动态库的句柄,该句柄是用来标识虚拟机核心动态库的,然后再调用地址获取函数,以虚拟机核心动态库的句柄为参数,从虚拟机核心动态库的句柄对应的述虚拟机核心动态库中,查找应用启动指令所对应的虚拟机实例的地址。
例如,文件打开函数可优选为dlopen函数(一种以指定模式打开指定的动态链接库文件,并返回一个句柄的函数),地址获取函数可优选为dlsym函数(一种根据动态链接库操作句柄与符号,返回符号对应的地址的函数),可以理解,通过dlopen函数可打开虚拟机核心动态库以获取虚拟机核心动态库的句柄,该句柄作为dlsym的输入参数,dlsym函数根据该虚拟机核心动态库的句柄以及虚拟机实例(相当于上述符号),获取虚拟机实例的地址。
在其中一个实施例中,查找应用启动指令所对应的虚拟机实例的地址的步骤之前,还包括步骤:响应应用启动指令,获取虚拟机版本号;当虚拟机版本号对应为Dalvik虚拟机时,进入查找应用启动指令所对应的虚拟机实例的地址的步骤。
Android系统上可运行两种类型的虚拟机,一种是Dalvik虚拟机,另一种是Art虚拟机,虚拟机有其对应的版本号,根据虚拟机版本号可确定虚拟机类型。只有在Android系统中运行的虚拟机为Dalvik虚拟机时,才能进行类验证模式的字段的地址所指向的值进行修改,从而在接收到应用启动指令后响应该应用启动指令,可进行虚拟机版本号的获取,在虚拟机版本号对应的虚拟机为Dalvik虚拟机时,后续可对虚拟机实例中的类验证模式字段的地址所指向的进行修改,即当虚拟机版本号对应为Dalvik虚拟机时,即可进入查找应用启动指令所对应的虚拟机实例的地址的步骤以及后续的修改动作。
下面以一个具体实施例对上述应用启动方法加以具体说明。
一般情况下,提升Android应用的启动速度的方案都是基于应用本身做的优化,没有深入系统层面做优化,在进行启动过程中加载类时需要进行类校验。具体地,如图6所示,Dalvik虚拟机(为Android操作系统设计的JAVA虚拟机)在首次加载Dex文件(Android系统的可执行文件)的过程中,会执行dexopt程序(Dalvik虚拟机中的程序,在应用安装或动态加载Dex文件时执行,对Dex文件进行校验和优化),逐行扫描Dex文件中每个类做字节码校验(即验证),包括校验每个类所依赖的类是否存在在该Dex文件中以及指令是否有效等方面的校验,校验通过,则对该类做存取指令、方法调用指令等优化,并对该类进行已校验标记(即打上CLASS_ISPREVERIFIED标记)。Dalvik虚拟机通常用于移动设备,如手机、平板电脑和可穿戴设备等,其指令集基于寄存器架构,执行其特有的Dex文件格式,它通过Dex字节码来完成对象生命周期管理、堆栈管理、线程管理、安全异常管理、垃圾回收等重要功能,它的核心内容是实现库(libdvm.so,即虚拟机核心动态库),大体由C语言实现。Dex文件包含应用的Dalvik指令、常量字符串等信息。在Android应用编译时,Java源文件被编译成Class(类)文件后,还需要使用dx工具(修复工具)将Class文件打包整合到Dex文件中。一个Dex文件中最多包含64K个方法数,对于方法数超过64K的应用,编译时将Class拆分打包到多个Dex中。
对于拆分多Dex文件的大型Android应用,Dex之间存在类相互引用,不能保证每个Dex文件中年类的依赖类都在本Dex中,所以会导致“类的依赖类是否在同一个Dex文件中”校验失败,进而导致很多类无法通过校验而无法标记已校验,即导致很多类无法打上打上CLASS_ISPREVERIFIED标记。如图7所示,应用每次执行启动过程中会调用dvmImitClass函数(类加载函数)加载类,需要判断类是否有被标记已校验,如果类没有被标记已校验,则需要对该类做字节码校验以及指令优化,即对于没有被标记已校验的类,应用每次运行加载时都会做字节码校验,不仅耗时且带来了较大的性能消耗,导致类加载缓慢,影响应用启动速度,从而导致应用启动速度不佳。
本实施例提出的应用启动方法可解决为上述类加载速度缓慢导致应用启动速度不加的问题,从系统层面优化,对应用本身的代码都是透明的,具有很强的通用性,即通过修改虚拟机实例中参数的值,即修改类验证模式字段对应的值,跳过类验证过程,提高类加载速度,从而提高应用启动速度。
具体地,分析dvmInitClass函数(类加载函数)源码,如果gDvm对象(DvmGlobals结构体实例,即虚拟机实例)中classVerifyMode(类验证模式字段)的值为VERIFY_MODE_NONE或者VERIFY_MODE_REMOTE时,会跳过类校验过程,并且把类的状态设置为已校验(CLASS_ISVERIFIED)。
分析DvmGlobals结构体(虚拟机实例)定义,classVerifyMode字段为DexClassVerifyMode枚举类型。
分析DexClassVerifyMode代码,枚举值包括VERIFY_MODE_UNKNOWN(表示未知是否要进行类校验,从而和VERIFY_MODE_ALL类似,所有类需要进行验证)、VERIFY_MODE_NONE、VERIFY_MODE_REMOTE(表示进行远程校验)和VERIFY_MODE_ALL(表示加载类时所有类要进行类验证)四种,其中,VERIFY_MODE_UNKNOWN=0,根据枚举类型的定义可知,VERIFY_MODE_NONE=1、VERIFY_MODE_REMOTE=2和VERIFY_MODE_ALL=3。虚拟机实例启动后会将DvmGlobals中classVerifyMode赋值为默认的VERIFY_MODE_ALL,即虚拟机实例启动后配置classVerifyMode为默认值3,本发实施例通过修改虚拟机实例中classVerifyMode字段的值为VERIFY_MODE_NONE,即修改虚拟机实例中classVerifyMode字段的值为3,以达到加载类时跳过类验证目的。
通过上述对各类的代码的分析,本实施例提出修改classVerifyMode字段的值来提高类加载速度,以实现应用启动速度的加快,如图8所示,具体流程如下:
(1)接收应用启动指令。接收到应用启动指令后触发修改流程开始。
(2)通过System.getProperty(“java.vm.version”)获取Android系统中运行的虚拟机版本号,System.getProperty(“属性”)函数用于获取系统相关属性的具体信息,此处的属性为虚拟机版本。
(3)根据虚拟机版本号判断虚拟机是否为Dalvik虚拟机,若是,则执行下述(4),否则跳转至(9)。
(4)使用dlopen函数打开虚拟机核心动态库(libdvm.so),获取虚拟机核心动态库的句柄,将该句柄座位dlsym函数的输入,通过dlsym函数获取gDvm对象(DvmGlobals结构体实例,即虚拟机实例)的地址。在本步骤中,调用dlopen和dlsym时,若出现异常,gDvm对象的地址即会获取失败,此时获取的gDvm对象地址为空。没有异常且地址非空表示地址获取成功。
(5)搜索gDvm对象中stackTraceFile字段(作为预设字段)的地址。stackTraceFile为一个指向/data/anr/traces.txt字符串的指针,所以其查找流程为:
(5.1)读取maps文件(地址信息记录文件),获取进程可读内存空间(可读地址列表)。
(5.2)初始化临时指针(int*p_gDvm),p_gDvm指向等于gDvm对象的地址。
(5.3)p_gDvm指针自增。
(5.4)根据可读内存空间判断p_gDvm指针指向的地址是否可读。
(5.5)如果可读,判断p_gDvm指针指向的地址所指向的值是否为指向/data/anr/traces.txt字符串的指针,即判断p_gDvm指针指向的地址所指向的值是否为/data/anr/traces.txt;否则,给出不可读提示信息,当获取到继续查找指令,则返回(5.3)。
(5.6)如果是,则p_gDvm指针指向的地址为stackTraceFile字段的地址,即为预设字段的地址;否则继续执行(5.3),直到指针自增次数达到400次,当指针自增次数达到400次时,跳转到步骤(9)。
(6)如果(5)中找到stackTraceFile字段地址,即p_gDvm指针指向的地址为stackTraceFile字段的地址,根据stackTraceFile字段的地址查找classVerifyMode字段的地址,具体地,由于stackTraceFile字段与classVerifyMode字段间相对位置关系为地址间隔3,将p_gDvm+3指向的地址作为classVerifyMode字段的地址。
(7)判断p_gDvm+3指向的地址所指向的值(即*(p_gDvm+3))是否为预期值3(3表示VERIFY_MODE_ALL),如果为3,执行下述(8);否则表明虚拟机配置不符合预期或者DvmGlobals结构体被厂商修改,跳转(9)。
(8)将p_gDvm+3指针的地址所指向的值修改为1(1表示VERIFY_MODE_NONE,即用于在加载类时跳过类验证的值)。
(9)停止修改,修改流程结束。
通过本实施例的应用启动方法对大型Android应用启动时,修改类验证模式字段的值,即该方法对应用业务代码是无侵入、透明的,接入成本小,通过提升类加载速度,达到提升应用启动速度的目的。终端上的社交应用上的对比实验验证了该方法的有效性。
请参阅图9,提供一个实施例的应用启动装置,包括:
指令获取模块110,用于获取应用启动指令。
第一地址查找模块120,用于查找应用启动指令所对应的虚拟机实例的地址。
第二地址查找模块130,用于按虚拟机实例的地址,查找虚拟机实例中类验证模式字段的地址。
修改模块140,用于将类验证模式字段的地址所指向的值,修改为用于在加载类时跳过类验证的值。
加载模块150,用于调用类加载函数,通过类加载函数并根据类验证模式字段的地址所指向的值,加载应用启动指令所对应的类。
通过上述应用启动装置,获取到应用启动指令,表示需要对应用进行启动,然后查找应用启动指令所对应的虚拟机实例的地址,根据虚拟机实例的地址,可查找到虚拟机实例中类验证模式字段的地址,将类验证模式字段的地址所指向的值修改为用于在加载类时跳过类验证的值,如此,在应用启动过程中,根据类加载函数以及类验证模式字段的地址所指向的值加载类时,无需对类进行验证,即跳过类验证过程,节省大量时间,提升类加载速度,从而提升应用整体的启动速度,可减少对业务逻辑使用的影响。
请参阅图10,其中一个实施例中,第二地址查找模块130包括:
预设查找模块231,用于按虚拟机实例的地址,查找虚拟机实例中指向预设固定值的预设字段的地址;
地址确定模块232,用于根据预设字段的地址,以及预设字段与类验证模式字段的相对位置关系,确定类验证模式字段的地址。
请参阅图11,其中一个实施例中,预设查找模块331包括:
指针初始化模块331,用于初始化临时指针,临时指针指向虚拟机实例的地址;
指针更新模块332,用于将临时指针加1;
读取模块333,用于读取临时指针指向的地址所指向的值;
地址配置模块334,用于当临时指针指向的地址所指向的值与预设固定值不同时,返回指针更新模块执行将临时指针增加1;当临时指针指向的地址所指向的值与预设固定值相同时,将临时指针指向的地址作为预设字段的地址。
在本实施例中,上述预设查找模块231还包括:
地址列表获取模块,用于获取可读地址列表,当临时指针指向的地址为可读地址列表中的可读地址时,进入上述读取模块333执行读取临时指针指向的地址所指向的值。
其中一个实施例中,应用启动装置还包括:记录模块。
预设查找模块还包括:停止模块。
记录模块,用于记录临时指针增加的次数。
地址配置模块334,用于当临时指针指向的地址所指向的值与预设固定值不相同,且增加的次数小于预设次数时,返回指针更新模块执行将临时指针增加1。
停止模块,用于当临时指针指向的地址所指向的值与预设固定值不相同,且增加的次数大于或等于预设次数时,停止对预设字段的地址的查找。
其中一个实施例中,修改模块140,用于当类验证模式字段的地址所指向的值为默认值时,将类验证模式字段的地址所指向的值修改为用于在加载类时跳过类验证的值;默认值在虚拟机实例启动时配置且用于触发类验证。
其中一个实施例中,第一地址查找模块120包括:
第一调用模块,用于调用文件打开函数打开虚拟机核心动态库,获得虚拟机核心动态库的句柄;
第二调用模块,用于调用地址获取函数并根据虚拟机核心动态库的句柄,查找应用启动指令所对应的虚拟机实例在虚拟机核心动态库中的地址,获取虚拟机实例的地址。
在其中一个实施例中,上述应用启动装置还包括:版本获取模块。
版本号获取模块,用于响应应用启动指令,获取虚拟机版本号;
第一地址查找模块120,用于当虚拟机版本号对应为Dalvik虚拟机时,执行查找应用启动指令所对应的虚拟机实例的地址。
本发明还提供一种实施例的计算机存储介质,其上存储有计算机程序,该计算机程序被处理器执行时实现上述应用启动方法的步骤。
本发明还提供一种实施例的计算机设备,包括存储器、处理器以及存储在存储器上并可在处理器上运行的计算机程序,处理器执行计算机程序时实现上述应用启动方法。
上述应用启动装置、计算机存储介质以及计算机设备中的技术特征分别与上述应用启动方法中的技术特征是对应的,在此不再赘述。
本领域普通技术人员可以理解实现上述实施例方法中的全部或部分流程,是可以通过计算机程序来指令相关的硬件来完成,的程序可存储于一非易失性的计算机可读取存储介质中,如本发明实施例中,该程序可存储于计算机系统的存储介质中,并被该计算机系统中的至少一个处理器执行,以实现包括如上述各方法的实施例的流程。其中,存储介质可为磁碟、光盘、只读存储记忆体(Read-Only Memory,ROM)或随机存储记忆体(RandomAccess Memory,RAM)等。
以上实施例的各技术特征可以进行任意的组合,为使描述简洁,未对上述实施例中的各个技术特征所有可能的组合都进行描述,然而,只要这些技术特征的组合不存在矛盾,都应当认为是本说明书记载的范围。
以上实施例仅表达了本发明的几种实施方式,其描述较为具体和详细,但并不能因此而理解为对本发明专利范围的限制。应当指出的是,对于本领域的普通技术人员来说,在不脱离本发明构思的前提下,还可以做出若干变形和改进,这些都属于本发明的保护范围。因此,本发明专利的保护范围应以所附权利要求为准。
Claims (14)
1.一种应用启动方法,其特征在于,应用于终端,包括以下步骤:
获取应用启动指令;
查找所述应用启动指令所对应的虚拟机实例的地址;
按所述虚拟机实例的地址,查找所述虚拟机实例中指向预设固定值的预设字段的地址;
根据所述预设字段的地址,以及预设字段与类验证模式字段的相对位置关系,确定所述类验证模式字段的地址;
将所述类验证模式字段的地址所指向的值,修改为用于在加载类时跳过类验证的值;
调用类加载函数,通过所述类加载函数并根据所述类验证模式字段的地址所指向的值,加载所述应用启动指令所对应的类。
2.根据权利要求1所述的应用启动方法,其特征在于,所述按所述虚拟机实例的地址,查找所述虚拟机实例中指向预设固定值的预设字段的地址的步骤包括:
初始化临时指针,所述临时指针指向所述虚拟机实例的地址;
将所述临时指针加1;
读取所述临时指针指向的地址所指向的值;
当所述临时指针指向的地址所指向的值与所述预设固定值不同时,返回所述将所述临时指针增加1的步骤;
当所述临时指针指向的地址所指向的值与所述预设固定值相同时,将所述临时指针指向的地址作为所述预设字段的地址。
3.根据权利要求2所述的应用启动方法,其特征在于,所述将所述临时指针加1的步骤之后还包括:记录所述临时指针增加的次数;
当所述临时指针指向的地址所指向的值与所述预设固定值不相同,且所述增加的次数小于预设次数时,返回所述将所述临时指针增加1的步骤;
当所述临时指针指向的地址所指向的值与所述预设固定值不相同,且所述增加的次数达到所述预设次数时,停止对所述预设字段的地址的查找。
4.根据权利要求1所述的应用启动方法,其特征在于,所述将所述类验证模式字段的地址所指向的值,修改为用于在加载类时跳过类验证的值的步骤包括:
当所述类验证模式字段的地址所指向的值为默认值时,将所述类验证模式字段的地址所指向的值修改为所述用于在加载类时跳过类验证的值;所述默认值在所述虚拟机实例启动时配置且用于触发类验证。
5.根据权利要求1所述的应用启动方法,其特征在于,所述查找所述应用启动指令所对应的虚拟机实例的地址的步骤包括:
调用文件打开函数打开虚拟机核心动态库,获得所述虚拟机核心动态库的句柄;
调用地址获取函数并根据所述虚拟机核心动态库的句柄,在所述虚拟机核心动态库中,查找所述应用启动指令所对应的虚拟机实例的地址。
6.根据权利要求1-5中任意一项所述的应用启动方法,其特征在于,所述查找所述应用启动指令所对应的虚拟机实例的地址的步骤之前,还包括步骤:
响应所述应用启动指令,获取虚拟机版本号;
当所述虚拟机版本号对应为Dalvik虚拟机时,进入所述查找所述应用启动指令所对应的虚拟机实例的地址的步骤。
7.一种应用启动装置,其特征在于,应用于终端,包括:
指令获取模块,用于获取应用启动指令;
第一地址查找模块,用于查找所述应用启动指令所对应的虚拟机实例的地址;
预设查找模块,用于按所述虚拟机实例的地址,查找所述虚拟机实例中指向预设固定值的预设字段的地址;
地址确定模块,用于根据所述预设字段的地址,以及预设字段与类验证模式字段的相对位置关系,确定所述类验证模式字段的地址;
修改模块,用于将所述类验证模式字段的地址所指向的值,修改为用于在加载类时跳过类验证的值;
加载模块,用于调用类加载函数,通过所述类加载函数并根据所述类验证模式字段的地址所指向的值,加载所述应用启动指令所对应的类。
8.根据权利要求7所述的应用启动装置,其特征在于,所述预设查找模块包括:
指针初始化模块,用于初始化临时指针,所述临时指针指向所述虚拟机实例的地址;
指针更新模块,用于将所述临时指针加1;
读取模块,用于读取所述临时指针指向的地址所指向的值;
地址配置模块,用于当所述临时指针指向的地址所指向的值与所述预设固定值不同时,返回所述指针更新模块执行将所述临时指针增加1;当所述临时指针指向的地址所指向的值与所述预设固定值相同时,将所述临时指针指向的地址作为所述预设字段的地址。
9.根据权利要求8所述的应用启动装置,其特征在于,
所述应用启动装置还包括:记录模块;
所述预设查找模块还包括:停止模块;
所述记录模块,用于记录所述临时指针增加的次数;
所述地址配置模块,用于当所述临时指针指向的地址所指向的值与所述预设固定值不相同,且所述增加的次数小于预设次数时,返回所述指针更新模块执行将所述临时指针增加1;
所述停止模块,用于当所述临时指针指向的地址所指向的值与所述预设固定值不相同,且所述增加的次数大于或等于所述预设次数时,停止对所述预设字段的地址的查找。
10.根据权利要求7所述的应用启动装置,其特征在于,所述修改模块,用于当所述类验证模式字段的地址所指向的值为默认值时,将所述类验证模式字段的地址所指向的值修改为所述用于在加载类时跳过类验证的值;所述默认值在所述虚拟机实例启动时配置且用于触发类验证。
11.根据权利要求7所述的应用启动装置,其特征在于,所述第一地址查找模块包括:
第一调用模块,用于调用文件打开函数打开虚拟机核心动态库,获得所述虚拟机核心动态库的句柄;
第二调用模块,用于调用地址获取函数并根据所述虚拟机核心动态库的句柄,在所述虚拟机核心动态库中,查找所述应用启动指令所对应的虚拟机实例的地址。
12.根据权利要求7-11中任意一项所述的应用启动装置,其特征在于,
所述应用启动装置还包括:版本获取模块;
所述版本获取模块,用于响应所述应用启动指令,获取虚拟机版本号;
所述第一地址查找模块,具体用于当所述虚拟机版本号对应为Dalvik虚拟机时,查找所述应用启动指令所对应的虚拟机实例的地址。
13.一种计算机存储介质,其上存储有计算机程序,其特征在于,该计算机程序被处理器执行时实现上述权利要求1-6中任意一项所述方法的步骤。
14.一种计算机设备,包括存储器、处理器以及存储在所述存储器上并可在所述处理器上运行的计算机程序,其特征在于,所述处理器执行所述计算机程序时实现如权利要求1-6中任意一项所述的方法。
Priority Applications (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN201710780649.3A CN109426546B (zh) | 2017-09-01 | 2017-09-01 | 应用启动方法及装置、计算机存储介质及设备 |
Applications Claiming Priority (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN201710780649.3A CN109426546B (zh) | 2017-09-01 | 2017-09-01 | 应用启动方法及装置、计算机存储介质及设备 |
Publications (2)
Publication Number | Publication Date |
---|---|
CN109426546A CN109426546A (zh) | 2019-03-05 |
CN109426546B true CN109426546B (zh) | 2022-10-25 |
Family
ID=65512937
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
CN201710780649.3A Active CN109426546B (zh) | 2017-09-01 | 2017-09-01 | 应用启动方法及装置、计算机存储介质及设备 |
Country Status (1)
Country | Link |
---|---|
CN (1) | CN109426546B (zh) |
Families Citing this family (1)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN111930467B (zh) * | 2020-07-02 | 2024-03-26 | 联想(北京)有限公司 | 虚拟机启动方法、装置、设备及计算机可读存储介质 |
Family Cites Families (5)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
US8364638B2 (en) * | 2005-09-15 | 2013-01-29 | Ca, Inc. | Automated filer technique for use in virtualized appliances and applications |
EP3422236B1 (en) * | 2012-10-10 | 2022-06-01 | Citrix Systems, Inc. | Policy-based application management |
CN104601324B (zh) * | 2013-10-30 | 2018-08-24 | 阿里巴巴集团控股有限公司 | 一种针对应用的验证方法、终端和系统 |
CN104731622B (zh) * | 2015-03-27 | 2016-10-05 | 北京奇虎科技有限公司 | 一种应用程序的加载方法、装置和移动终端 |
CN106909356A (zh) * | 2015-12-22 | 2017-06-30 | 阿里巴巴集团控股有限公司 | Java类中方法的替换方法和装置 |
-
2017
- 2017-09-01 CN CN201710780649.3A patent/CN109426546B/zh active Active
Also Published As
Publication number | Publication date |
---|---|
CN109426546A (zh) | 2019-03-05 |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
CN108027722B (zh) | 在编译和部署中动态更新应用 | |
CN107526625B (zh) | 一种基于字节码检查的Java智能合约安全检测方法 | |
CN107451474B (zh) | 用于终端的软件漏洞修复方法和装置 | |
US9858057B2 (en) | Methods and apparatus to validate translated guest code in a dynamic binary translator | |
CN110990019B (zh) | 一种Java类分析方法、装置、存储介质及电子设备 | |
CN106648755B (zh) | 一种在安卓art环境中动态加载dex的方法及装置 | |
CN109271789B (zh) | 恶意进程检测方法、装置、电子设备及存储介质 | |
CN111679852B (zh) | 一种冲突依赖库的检测方法及装置 | |
CN107643893B (zh) | 一种程序检测方法及装置 | |
US11157249B1 (en) | Method and system for identifying and extracting independent services from a computer program | |
CN111523097A (zh) | 基于安卓系统的app刷子用户识别方法、设备及存储介质 | |
CN107463485B (zh) | 基于方法栈的日志获取方法、装置和终端 | |
CN113391874A (zh) | 一种虚拟机检测对抗方法、装置、电子设备及存储介质 | |
CN109426546B (zh) | 应用启动方法及装置、计算机存储介质及设备 | |
US20120222023A1 (en) | Automatic runtime dependency lookup | |
CN115659340B (zh) | 一种仿冒小程序识别方法、装置、存储介质及电子设备 | |
WO2023179298A1 (zh) | 应用程序更新、应用程序开发方法、装置及计算机设备 | |
CN111880804A (zh) | 应用程序代码的处理方法及装置 | |
CN114610516B (zh) | 应用程序的修复方法、装置、计算机设备以及存储介质 | |
CN111796832B (zh) | 热补丁文件生成方法、装置、设备及存储介质 | |
KR102341137B1 (ko) | 중간언어 기반 코드 변환 방법 및 이를 포함하는 전자 장치 | |
CN114706586A (zh) | 代码编译、代码运行方法、装置、计算机设备及存储介质 | |
CN111240728A (zh) | 应用程序更新方法、装置、设备和存储介质 | |
CN112579156A (zh) | 一种业务事件的处理系统以及处理方法、装置和设备 | |
CN107451050B (zh) | 函数获取方法和装置、服务器 |
Legal Events
Date | Code | Title | Description |
---|---|---|---|
PB01 | Publication | ||
PB01 | Publication | ||
SE01 | Entry into force of request for substantive examination | ||
SE01 | Entry into force of request for substantive examination | ||
GR01 | Patent grant | ||
GR01 | Patent grant |