CN110362363B - 一种基于运行时模型实现对终端应用控制的方法 - Google Patents
一种基于运行时模型实现对终端应用控制的方法 Download PDFInfo
- Publication number
- CN110362363B CN110362363B CN201910498732.0A CN201910498732A CN110362363B CN 110362363 B CN110362363 B CN 110362363B CN 201910498732 A CN201910498732 A CN 201910498732A CN 110362363 B CN110362363 B CN 110362363B
- Authority
- CN
- China
- Prior art keywords
- activity
- model
- runtime
- control
- application
- 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
- G06F8/00—Arrangements for software engineering
- G06F8/30—Creation or generation of source code
-
- 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/448—Execution paradigms, e.g. implementations of programming paradigms
- G06F9/4482—Procedural
Landscapes
- Engineering & Computer Science (AREA)
- Software Systems (AREA)
- Theoretical Computer Science (AREA)
- General Engineering & Computer Science (AREA)
- Physics & Mathematics (AREA)
- General Physics & Mathematics (AREA)
- Stored Programmes (AREA)
- Control Of Eletrric Generators (AREA)
- Feedback Control In General (AREA)
Abstract
本发明公开了一种基于运行时模型实现对终端应用控制的方法,通过定义运行时模型上的操作以及模型片段在堆、栈区域影响的等价性,实现了复杂的应用行为模型的分解,可操作的模型片段,并基于分解的模型片段,建立行为模型与应用状态和应用代码的因果关联,实现了在终端应用运行时对其应用行为的指令级别的控制。
Description
技术领域
本发明涉及计算机技术,尤其涉及一种基于运行时模型实现对终端应用控制的方法。
背景技术
网构软件(也称终端应用)是在互联网开放、动态和多变环境下软件***基本形态的一种抽象,它既是传统软件结构的自然延伸,又具有区别于集中封装环境下发展起来的传统软件形态的独有基本特征:1)自主性,指网构软件***中的软件实体具有相对独立性、主动性和自适应性。自主性使其区别于传统软件***中软件实体的依赖性和被动性;2)协同性,指网构软件***中软件实体与软件实体之间可按多种静态连接和动态合作方式在开放的网络环境下加以互连、互通、协作和联盟。协同性使其区别于传统软件***在封闭集中环境下单一静态的连接模式;3)反应性,指网构软件具有感知外部运行和使用环境并对***演化提供有用信息的能力。反应性使网构软件***具备了适应开放、动态和多变环境的感知能力;4)演化性,指网构软件结构可根据应用需求和网络环境变化而发生动态演化,主要表现在其实体元素数目的可变性,结构关系的可调节性和结构形态的动态可配置性。演化性使网构软件***具备了适应比开放、动态和多变环境的应变能力;5)多态性,指网构软件***的效果体现出相容的多目标性。它可根据某些基本协同原则,在动态变化的网络环境下,满足多种相容的目标形态。多态性使网构软件***在网络环境下具备了一定的柔性和满足个性化需求的能力。
上述网构软件特征的实现,往往需要在运行态修改软件以保障或改善质量、优化或新增功能。经典软件工程方法与技术强调在开发态修改软件,不支持运行态直接修改软件。
与之对应,编程语言、操作***、中间件等***软件,提供了一种常见的运行态监测与控制应用的主要机制——计算反射(computational reflection,简称反射)。基于计算反射可以实现各种开发框架、测试框架,以提高开发人员在代码开发、测试甚至运行部署中的效率。在计算机领域,B.Smith给出了通用的反射性的定义:反射性是实体具有按照描述、操作和处理实体所面临的主要问题域的相同方式来描述、操作和处理实体自身的一种能力。该定义后续被解释为:反射性是程序具有在运行时刻操纵一组数据的能力,这组数据描述了该程序的运行状态,操纵有两方面含意:1)监测(Introspection),程序可以观测并推理自身的状态;2)控制(Intercession),程序可以改变自身的运行或语义。而这两方面都需要能将程序执行的状态编码为数据,而提供这种编码便称为反射也就是说,反射其实是将程序的运行状态映射为一组可操作的数据。前一部分组成基层实体,后一部分组成元层实体,而基层实体与元层实体之间保持了因果关联。根据基层实体的不同,计算反射主要分为结构反射和行为反射。结构反射的基层实体为当前程序及其抽象数据类型(可视为应用的状态),而行为反射的基层实体则是当前程序的执行行为及其执行所需的数据(可视为应用的行为)。
结构反射是指编程语言提供对当前程序及其抽象数据类型反射的能力,由于与编程语言框架(runtime或framework)的能力类似而自然存在,是大多数编程语言框架固有的能力。
行为反射是指编程语言提供对自身的执行语义及其执行所需的数据反射的能力,也就是编程语言框架自身需要被反射,行为反射在监测和控制上面临两个挑战:其一,需要完整描述既有的应用行为,也就是对应用的执行进行监测。应用的执行可视为一组运行时活动的集合,活动的粒度越细,监测的信息也越丰富,监测功能占用的资源就越大,其与业务逻辑之间的资源竞争也就越严重。此时,应用行为监测的复杂性和规模性就成为终端应用行为反射的首要挑战。其二,现有编程语言以及操作***和中间件等***软件的行为反射,均不支持指令级的行为控制,根本原因在于指令序列蕴含的复杂的数据和控制依赖,因此,应用行为的指令级控制就成为终端应用行为反射的主要难点。
发明内容
本发明主要目的在于,提供一种基于运行时模型实现对终端应用控制的方法,克服上述第二个挑战,实现对终端应用行为进行指令级控制。
本发明是通过如下技术方案实现的:
为解决上述技术问题,本发明提出了一种基于运行时模型实现对终端应用控制的方法,所述运行时模型包括运行时栈模型和运行时堆模型,包括:
预定义对所述运行时模型的操作以及模型片段在堆、栈区域影响的等价性;
对所述运行时模型保持所述等价性进行转换,对所述运行时模型进行分解,得到一组可操作的模型片段;
根据分解后的模型片段,建立所述运行时模型与应用状态和应用代码的因果关联,以对所述终端应用行为进行控制。
进一步的,所述运行时模型包括一段时间内发生的一组具有逻辑关联的活动的集合;
所述预定义对所述运行时模型的操作包括:
增加,用于在原有活动执行流程中增加一部分程序活动;
删除,用于消除原有活动执行流程中执行的活动对程序本身的影响;
修改,用于在消除原有活动的影响后,重新执行修改的活动。
进一步的,对所述终端应用行为进行控制包括对所述终端应用行为进行行为式控制和/或结构式控制。
进一步的,对所述终端应用行为进行行为式控制的步骤包括:
设终端应用的内存初始状态S,活动序列A;
经过一段时间的执行,获取所述运行后的内存状态为S·A=S',对所述运行时模型保持所述等价性进行转换后的活动序列为A',得到目标状态为S.A'=S”;
利用S.A'=(S.A).A”=S'.A”求解增量活动序列A”,使得A+A”=A',完成对所述终端应用行为进行行为式控制的过程。
进一步的,所述增量活动序列A”包括:控制转移、算术运算、字段读取、数组读取、类实例化、数组实例化,字段赋值、数组赋值、线程同步、垃圾回收、方法调用和类加载。
进一步的,对所述终端应用行为进行结构式控制的步骤包括:
获取终端应用行为的运行时模型M,一组操作以及一个转换后的活动序列A';
将所述一组操作映射为一段目标代码,以使所述目标代码的执行所产生的活动序列A”与活动序列A'保持控制等价关系。
进一步的,针对任意活动,将所述一组操作映射为一段目标代码的步骤包括:
获取数据依赖,使得所述活动执行的数据依赖与活动发生时刻相同;
将所述活动转换为相应的目标代码。
进一步的,所述数据依赖包括数值类型和对象类型;
对于一个活动,当其依赖的数据类型为数值类型时,直接采用运行时模型中活动执行时对应的数值;
对于一个活动,当其依赖的数据类型为对象类型时,分为局部对象和全局对象;其中,当其依赖的数据类型为局部对象时,通过回放与该对象相关活动的方式生成构造所述局部对象的代码;当其依赖的数据类型为全局对象时,通过程序分析构造出一组可达的对象引用链以获取该对象,根据对象之间的引用类型,自动生成动态数据依赖相关的代码。
进一步的,针对所述局部对象的构造,包括基于活动序列构造的局部对象构造和基于运行时堆模型的局部对象构造。
进一步的,所述全局对象根据运行时堆模型中的引用链获得。
与现有技术相比,本发明通过定义运行时模型上的操作以及模型片段在堆、栈区域影响的等价性,实现了复杂的应用行为模型的分解,可操作的模型片段,并基于分解的模型片段,建立行为模型与应用状态和应用代码的因果关联,实现了在终端应用运行时对其应用行为的指令级别的控制。
附图说明
图1是现有3G无线资源控制状态机;
图2(a)是一个网络请求合并的实例中合并前的网络请求控制流示意图;
图2(b)是一个网络请求合并的实例中合并后的网络请求控制流示意图;
图3是一个线程之间通信依赖的例子——生产者-消费者模式示意图;
图4是本发明实施例一种基于运行时模型实现对终端应用控制的方法的步骤流程图;
图5是自动重构实现网络请求调度的栈模型示例;
图6(a)是面向用户的图形界面接口发消息执行流程示意图;
图6(b)是面向互操作的发送消息接口的执行流程示意图;
图7是本发明示例Reflectall模型生成子***架构示意图;
图8是本发明示例Reflectall的接口运行子***的结构示意图;
图9(a)是本发明示例计算器的原始类图;
图9(b)是本发明示例修改后的类图。
具体实施方式
为使本发明的目的、技术方案和优点更加清楚明白,下面结合实施例和附图,对本发明作进一步详细说明。
为了更好理解本申请的技术问题,本发明采用选取两个典型案例的应用功能演化场景进行分析,以此来明确现有的行为反射不适用的根本原因。
案例一:
随着智能手机的发展,终端的移动应用越来越依赖云端提供的软件、硬件资源,以提供更好的服务。然而,云端与终端之间的通讯需要消耗大量的电能。联网应用(如天气、邮件、新闻等)呈现了网构软件典型的构件化特点,利用网络实现了终端与云端各构件的通讯。特别在3G/4G环境下,联网应用在后台长时间、间隔式地利用网络获取相应的推送消息。这种长时间、间隔式的消息推送给电池容量有限的智能手机的续航带来了巨大压力。3G和4G是当前主流使用的移动蜂窝网络,其耗电特点更为复杂。一方面,因为蜂窝网络移动性较强,对于一个移动设备,随着物理位置的移动,可能快速切换到不同蜂窝网络基站。因此,对于蜂窝网络基站,不可能将一个信道一直分配给一台移动设备。另一方面,由于移动设备续航有限,而长时间连接至蜂窝网络基站,会大大提高其功耗,影响续航。因此,蜂窝网络标准中,进一步对无线资源控制(Radio Resource Control,RRC)模块的状态进行了规定。
以移动设备中的3G网络模块为例,一共包含三个状态,如图1所示。
(1)IDLE:即空闲状态,在此状态下,3G模块的耗电最低,同时也不能发送、接收任何数据。在这个状态下,如果要发送或接收数据,则会转移至CELL_DCH状态。
(2)CELL_DCH:在这个状态下,3G模块的带宽达到最大,此时能以最大的速率进行数据传输,同时它的功耗也是最大的。如果持续一段时间,仍然没有数据传输的话,它会转移至CELL_FACH状态。根据不同的运营商的设置,持续运行于CELL_DCH状态的时间通常是5秒至10秒。
(3)CELL_FACH:在这个状态下,3G模块的耗电比CELL_DCH要节省50%,同时,在这个状态下,其网络传输速率也较低。如果在这个状态,发送或接收的数据大于某个阀值,则会重新转移至CELL_DCH状态。而如果在CELL_FACH状态持续一段时间没有发送或接收数据,则会转移至IDLE状态。一般来说这段时间通常是10秒至15秒。
图2展示了一个网络请求合并的实例。图2(a)为合并前的网络请求与无线通讯模块耗电,其横轴为时间,上半部分为无线通讯模块的功耗;下半部分的虚线为发起这两个网络请求的线程;下半部分的实线为其控制流。首先,一个后台的新闻推送线程唤醒了负责发送网络请求的线程①;该线程被唤醒后,发起了网络请求②,此时,无线通讯模块的功耗也由IDLE状态下的低功耗,变为CELL_DCH状态下的高功耗;当整个请求完成后,负责发送网络请求的线程将结果返回给新闻推送线程③,此时虽然无线通讯模块没有接收或发送数据,但它仍会保持在高功耗状态,由此开始的无线通讯模块耗电被称之为“尾时间耗电”,对应为图2(a)中用的斜线部分;新闻推送线程在收到返回结果后④,对结果进行处理,并在通知栏上进行提示⑤。又过了一段时间后,另一个版本更新线程也执行了类似的逻辑⑥,发送了网络请求。如图2(a)所示,由于这两个网络请求间隔了几十秒,导致无线通讯模块被唤醒了两次,因此也有了对应的两次“尾时间”,由此导致了额外的网络能耗。
对于安卓应用,有很大一部分后台请求可以被延迟几十秒、甚至两、三分钟,而不会影响用户的体验。例如上述的新闻推送、版本更新推送等。对于这些网络请求,如果在时间维度上进行合并,即两个请求同时发送,而不是间隔了几十秒发送,就可以减少“尾时间”的网络耗电。图2(b)为图2(a)中两个请求进行了合并后的控制流及其无线通讯模块耗电情况。首先,负责发送网络请求的线程被新闻推送线程唤醒后,并不直接发送网络请求,而是进入一个等待状态⑦。一段时间后,另一个网络请求线程被后台更新推送线程唤醒,同时,它也进入一个等待状态⑧。在等待状态结束后⑨,这两个线程同时发送网络请求,对应的无线通讯模块也只被唤醒一次。如图2(b)所示,合并后的网络请求的耗电要远小于合并前的网络请求耗电。
为了实现网络请求合并,需要1)一种网络请求调度机制,即,使原本直接发送的网络请求可被延迟发送;2)一种网络请求调度算法,即找出可被延迟调度的请求,同时利用调度机制进行延迟发送。利用结构反射可以实现自动化重构移动应用的网络请求执行逻辑,并把调度机制内置进应用。然而这就要求不同应用的开发者均使用同一个自动重构框架,并且需要对所有应用进行重新的编译、部署和运行。这对于大量的、分属于不同应用开发者的闭源应用显然不现实。
案例二:
随着微信的普及,微信已经不仅仅是一个简单的通讯应用,它还成为了工作交流的必备工具;催生了利用微信朋友圈、公众号进行营销的“微商”;成为了最大的自媒体的发布平台。微信其核心作为一个通讯工具,其功能还是以满足普通用户为主。即便如此,它也很难满足普通用户的特定需求。例如,随着微信使用的时间越来越长,其缓存的聊天记录文件也越来越大,对于普通用户而言,很难对自己的聊天日志进行管理。更进一步地,微信难以满足微商、自媒体人等特殊群体的特定的需求。要实现微信应用内数据与功能的开放共享,就需要将面向用户的用户界面接口转换为面向互操作的可编程接口。一般而言,对于面向用户的用户界面接口,其执行的起点在于用户界面元素的点击、拖动和输入等操作。经过部分的逻辑处理,以网络请求、数据库查询、文件读写的方式,访问外部资源,获取相应的数据或实现相应的功能。在该处理流程中,有大部分的逻辑是与面向互操作的可编程接口的执行逻辑是相似的,只是其执行的起点不同。然而,现有的行为反射监测和控制的粒度为方法级别。基于现有的行为反射,在既有应用的执行流程中***某些执行逻辑的方式,难以实现将面向用户的用户界面接口转换为面向互操作的可编程接口:既有的功能可对应于运行时的一组程序活动,以方法为粒度的行为反射其监测的内容有限,无法监测方法内的指令的执行,继而也无法控制。这就导致了现有的解决方案往往是基于既有的代码和文档,对于一个开发团队而言,开发人员的流动、文档的缺失、甚至是不规范的源码注释都会使得移动应用的迭代开发变得难以进行。
由上述两个案例分析可以看出,难以实现移动应用互操作接口根本原因在于现有的工作由于缺乏对应用行为的一个完整、详实的描述,同时也没有对这种指令粒度的自描述的控制的方法。
其中,行为反射的监测可采用现有相关监测技术实现,比如采用Xposed框架进行监测,Xposed框架是一款可以在不修改APK的情况下监测和修改程序运行行为的框架服务(rovo89,2012)。此部分属于现有技术,不属于本发明的重点,在此不多赘述。但行为反射的控制在现有技术中较少,由此对这种指令粒度的自描述的控制的方法为本发明问题的难点和关键。
针对上述技术问题,本发明实施例提出了一种基于运行时模型实现对终端应用控制的方法,所述运行时模型包括运行时栈模型和运行时堆模型。
应用在操作***中运行起来之后,可视为一个或多个进程,操作***将移动应用所需的可执行文件加载到内存中,并开始执行。一般而言,一个进程所占的内存可分为三个区域:
代码段:存放执行代码的一块内存区域,具有只读属性;
堆区:可分为用于存放全局变量的一块内存区域(数据段),和用于进程运行中动态分配的内存区域,例如,面向对象编程语言Java中,线程创建一个新的对象相当于在堆区中申请了一片内存;
栈区:用于临时存局部变量等。例如,面向对象编程语言Java中,线程调用一个方法时,会新申请一个帧(frame),帧中保存了方法所需的参数等数据。
经过发明人仔细研究发现,终端应用在运行时,代码段的执行会引起堆区和栈区内存数据的变化。应用的运行时模型需要能反映应用在一段时间内的:1)代码的执行情况:在开发时,移动应用的代码可抽象为控制流图,那么对应于运行时,代码的执行情况可抽象为控制流图的一条或多条路径;2)内存数据(如堆区)的变化:在开发时,开发人员会设计好各种数据结构以表示应用的数据模型(Data Model),而在运行时,代码的执行引起对这些数据结构的实例的创建、修改、删除,也就是对应于一组内存的分配和修改操作。从内存区域角度上看,程序执行所影响的最主要的区域是内存的栈区和堆区。1)中的控制流图中的路径可视为对栈变化的一个描述,而2)中主要体现的是堆区数据的变化。
因此,本发明所构造的应用运行时模型包括一个描述栈变化的运行时栈模型和一个描述堆变化的运行时堆模型。其中运行时栈模型还包括对代码的获取,以此将一个进程所占的内存完整的分为三个区域。通过本发明实施例的运行时栈模型,可以了解在任意时刻移动应用的代码执行情况;而通过运行时堆模型,可以了解在任意时刻代码执行所依赖的对象数据状态。
运行时栈模型
控制流图为一个有向图G=<B,P>;
其中,B={b1,b2,…,bn}为基本块;
对于任意pi=(bi1,bi2),pi∈P,当且仅当bi2可能bi1之后执行。而在运行时,控制流图会实例化为一个或多个控制流,并按照控制流图中的路径执行基本块。本发明称在某一时刻执行的基本块为活动,则一段时间内的运行时栈模型是由控制流图,一个或多个控制流,和一组活动序列组成。当基本块的粒度为指令粒度时,活动序列就是指令执行序列。下面给出本发明所述的运行时栈模型的形式化定义。
定义运行时栈模型为一个或多个控制流在一段时间内发生的活动的集合m=<G,T,A,I,E>,
其中,G=<B,P>为控制流图,T={t1,t2,…,tn}为一组时刻,I={i1,i2,…,in},表示t1至tn时刻的程序的堆区状态。
运行时栈模型可视为控制流图的多条路径的集合,因此,在运行时栈模型中的边必须在控制流图中有相应的边。即:其中ai=(fi1,ti2,bi3),aj=(fj1,tj2,bj3)aj=(fj1,tj2,bj3),有(bi3,bj3)∈P。除此之外,运行时栈模型的边表示两个活动发生的前后关系,对于在同一控制流中的两个活动,具有时间上的前后顺序关系;对于在不同控制流中的两个活动如果存在边,则表明这两个活动间还具有依赖关系。
在同一个控制流中,若有两个活动具有前后***,则对于任意的其他活动,都不可能在同一控制流的这两个活动之间发生,即其中ai=(fi1,ti2,bi3),aj=(fj1,tj2,bj3),如果fi1≠fj1,则
在不同控制流中,若两个活动具有前后***,则对于后一个活动所在的控制流,在发生前一活动的时刻之后,可以先发生其他活动。其中ai=(fi1,ti2,bi3),aj=(fj1,tj2,bj3),如果fi1≠fj1,则ti2<tj2。
定义程序活动aj同步依赖于程序活动ai,如果aj的开始或结束由ai的执行决定,一般地,而ai往往是一些线程同步操作。称aj通信依赖于ai,如果aj的某项数据依赖是由ai活动产生。以面向对象编程语言Java为例,基本块的粒度为源代码的基本块的粒度。运行栈模型的每一个控制流对应于一个Java线程的执行序列。线程的状态转移共有六种状态:
创建:线程对象刚创建,还未开始时处于该状态;
运行:线程处于正在运行的状态,在该状态的线程可能等待一些***资源,如CPU;
阻塞:线程正在等待某个监控锁(Monitor Lock),例如线程在进入synchronized关键字修改的方法或是代码块时,线程会进入阻塞状态;
等待/定时等待:线程正在等待,例如,当线程调用某个对象的wait方法进入等待状态。当该对象的notify方法被该用时,线程会重新进入运行状态;
死亡:当一个线程的run方法执行结束后,会进入死亡状态。
由以上的状态转换可以发现,在某些情况下,某一个处于运行状态的线程可以唤醒另一个处于非运行状态的线程进入运行状态。本发明称线程之间的这种关系为同步依赖关系。在这些线程间唤醒发生时,对应于运行时栈模型中,处于运行状态的线程发生的活动会与非运行状态线程进入运行状态时发生的活动存在一条跨线程(跨控制流)的边。从Java的语言层面,可将这些线程依赖归纳为四类,如表1所示。
表1:Java语言层面的同步依赖关系分类
在表1中,每个运行线程的活动都会与非运行线程的活动对应。因此,称表1中的线程间依赖关系为同步依赖关系。基于以上线程的状态转换,Java提供了多种多线程编程库,以支持,例如java.util.concurrent中提供了读写锁、可重入锁、阻塞锁和线程池等。
图3展示了一个线程之间通信依赖的例子——生产者-消费者模式。在该例子中,Task类表示计算任务;静态字段tasks表示待处理任务队列;postTask方法表示生成并提交任务;handleTask方法表示处理任务。如图3所示,存在两个线程:1)线程1表示生产者线程,会提交任务至待处理任务队列;2)线程2表示消费者线程,每隔一段时间便会查看待处理任务队列,并处理相应的任务。在这个例子中,生产者线程与消费者线程之间并无同步依赖关系——消费者线程每隔一段时间便自动由定时等待状态转为运行状态,但是却存在通信的依赖关系——如果生产者线程不提交任务,消费者线程的task.run方法便不会被调用。
由上述例子可以发现,运行时栈模型中的活动关系的生成必须依赖运行时的相应数据。在经典的数据流分析中,数据流分析算法会根据控制流图的结构计算数据流方程,并迭代至稳定点。因此,应用的运行时模型除了上述的运行时栈模型外,还需一个描述内存堆区数据状态变化的运行时堆模型。
运行时堆模型
经典的数据流图常用于需求分析阶段。软件利用数据流图由抽象到具体、逐层分解待开发的软件***。数据流图为一个有向图,包含了两种不同类型的边和多种不同的节点用以描述数据从一个初始节点出发,进行层层计算,最后得到最终结果。在运行时,数据流图的某个节点本质上对应了一组内存数据的变化。因此,本发明的应用的行为运行时模型的堆模型重点关注内存数据的变化,而不是变化的操作。本发明所述的运行时的堆模型仅从内存数据变化角度对应用运行时的内存的堆区进行建模。
运行时堆模型是由一组内存数据的初始值和在一段时间内发生堆的内存修改活动的集合M=<D,A,T,R>;
其中,D={d1,d2,…,dn},为一组内存地址的初始值,A={i1,i2,…,in},为引起内存数据变化的活动,T={t1,t2,…,tn},为时间戳。
对于不同的面向对象编程语言,它们会提供不同的应用编程接口以实现内存的动态分配和回收。例如C/C++语言,通过在标准库函数中提供malloc和free函数实现内存的分配和回收;而Java语言,通过new关键字可创建新的对象,实现内存的分配,通过自动的垃圾回收机制,实现对内存的回收。
通过上述模型介绍,可了解到,实现应用行为的灵活控制面临着控制的多态性和实用性的挑战:一方面,由于监测的基层实体为应用运行时的行为,因此控制就体现为对运行时行为的修改,然而对模型中的每一个活动均为发生过的活动,如何正确地定义对运行时状态的修改;另一方面,控制还可以体现为实现部分结构反射,正如利用结构反射可以实现部分行为反射,如何基于行为反射实现部分结构反射。由于各种编译优化技术,提供的源代码往往不能直接与运行时执行的指令对应起来,实用性不高,因而本框架需要支持编译优化后的应用。
针对上述技术问题,接下来对如何实现对这种指令粒度的自描述的控制进行详细阐述。
参照图4,示出了本发明实施例一种基于运行时模型实现对终端应用控制的方法的步骤流程图,包括:
步骤S401:预定义对所述运行时模型的操作以及模型片段在堆、栈区域影响的等价性;
步骤S402:对所述运行时模型保持所述等价性进行转换,对所述运行时模型进行分解,得到一组可操作的模型片段;
步骤S403:根据分解后的模型片段,建立所述运行时模型与应用状态和应用代码的因果关联,以对所述终端应用行为进行控制。
在本发明一优选实施例中,所述运行时模型包括一段时间内发生的一组具有逻辑关联的活动的集合;
所述预定义对所述运行时模型的操作包括:
增加,用于在原有活动执行流程中增加一部分程序活动;
删除,用于消除原有活动执行流程中执行的活动对程序本身的影响;
修改,用于在消除原有活动的影响后,重新执行修改的活动。
定义如下:
应用运行时行为模型的操作:令M=<G,T,A,I,E>为应用行为运行时模型,a=(t,i,b),且a∈A,操作集合为OpSet={Add,Delete,Transform},操作Op∈OpSet,其中:
Add:A→A∪{a}
Delete:A→A-{a}
Transform:A→A-{a}∪{a′}。
利用上述的三个操作,可以实现对应用运行时模型中的一组活动的修改。活动序列对内存的控制体现为对内存的读、写操作。对于两级不同的活动,可能对内存产生相同的控制。下面,本发明从内存状态的角度,对控制的等价性作如下定义:
由此引出存控制等价的定义如下:
下面以案例一中的自动重构字节码以实现网络能耗优化的代码作为示例,来对活动序列的控制的等价性做进一步阐述。
案例一的图2所对应的运行时栈模型如图5所示,由图5可以发现,发送网络请求的过程由重构前的②→③变为⑦→⑧,这两个活动序列的栈的变化不相同:这是由于有了额外的调度器NetworkStub。因此,这两个活动序列不是栈控制等价。但是,发送网络请求的过程中,与应用原有执行逻辑的堆的变化情况是相似的:重构前、后,与应用业务逻辑相关的对象的变化保持一致;重构之后,堆中新增了与网络请求调度逻辑相关的对象。因此,仅从与应用原有执行逻辑相关的对象的角度上看,这两个活动序列是堆控制等价。也就是说,这个自动重构是一个实现堆控制等价的重构。类似例子还有利用自动重构实现代码覆盖率报告成的工具,如Emma,JCover,它们自动重构前、后的应用均是保持了原应用的任意一个方法重构前、后的执行序列保持了堆控制等价。由此可发现,重构前后的堆控制等价保证了程序执行的功能一致性。
以案例二的微信应用面向互操作的接口生成为例,既有面向用户的图形界面接口实现发消息的应用行为运行时模型可抽象为如图6(a)所示的顺序图:首先由用户触发界面层的对象向控制层的对象发送消息①,应用的执行逻辑在控制层和数据层切换执行(②→④);当结果返回时,将结果通知界面层对象⑤。假设图6(b)为面向互操作的发送消息接口的执行流程,可以发现这两个执行流程中②→④与⑦→⑨,即后台线程与服务器的交互过程中,其活动的执行保持了栈控制等价与堆控制等价。虽然整个交互过程中这两个活动序列对堆的控制不等价:面向互操作的接口不依赖界面相关的元素,而面向用户的接口依赖聊天窗口对象;对栈的控制也不等价:只有面向用户的接口执行过程涉及了用户界面线程。
上述案例表明,通过重构前、后的应用执行流程的堆控制等价来保证重构前后应用业务逻辑的一致性,并增加正交于业务逻辑的功能,例如,生成代码覆盖报告、调度网络请求。从结构反射的控制来看,一方面,其本质是修改了应用的代码,进而影响了应用的执行流程。另一方面,基于结构可以实现行为反射,即实现对应用执行流程的监测与修改。这也意味着,对于基于行为解释器实现的行为反射,其控制也有了两方面的含意。一方面,行为反射的控制本质上需要修改应用执行的行为。另一方面,如果将运行时的行为序列作为程序,通过行为的修改,也可实现对应用代码的修改。因此,行为反射的控制在一定程度上也能实现结构反射。下面,给出本发明对基于运行时模型的行为控制的分类与定义。
控制的分类:应用行为运行时模型可视为应用执行某一项功能时的一个完整的顺序图,其所描述是在一段时间内发生的一组具有逻辑关联的活动的集合。如果把应用运行时模型视为一组对内存产生影响的活动,那么增加、删除、修改则意味着对当前程序运行状态的修改。而如果把应用运行时模型视为一段执行过的代码,则增加、删除、修改意味着对这段代码的修改,而对应用的控制就体现为生成了一段新的代码。
在本发明优选实施例中,对所述终端应用行为进行控制包括对所述终端应用行为进行行为式控制和/或结构式控制。本发明将对当前应用内存直接产生影响的控制定义为行为式控制,而将这种可以产生新的应用代码的控制定义为结构式控制。
(1)行为式控制
行为式控制强调直接对原应用的状态进行控制和修改,即在不生成或编写新的代码片段、不重新编译、不重新启动应用的情况下,对原应用状态和行为进行控制。行为式控制将行为运行时模型视为一组发生过的活动,对行为运行时模型的操作意味着修改原应用的已经发生过的活动对内存状态的影响。
在本发明实施例中,对所述终端应用行为进行行为式控制的步骤包括:
设终端应用的内存初始状态S,活动序列A;
经过一段时间的执行,获取所述运行后的内存状态为S·A=S',对所述运行时模型保持所述等价性进行转换后的活动序列为A',得到目标状态为S.A'=S”;
利用S.A'=(S.A).A”=S'.A”求解增量活动序列A”,使得A+A”=A',完成对所述终端应用行为进行行为式控制的过程。
下面,根据运行时发生的不同活动的增加、删除和修改操作的语义给出行为式控制所需的增量活动序列A”:所述增量活动序列A”包括:控制转移、算术运算、字段读取、数组读取、类实例化、数组实例化,字段赋值、数组赋值、线程同步、垃圾回收、方法调用和类加载。
控制转移:控制转移活动所对应的指令包括if系列指令、switch系列指令等。对于一条转移控制指令,其执行的效果为继续执行、或跳转至某个分支。如果修改所影响的是程序的结构,那么就需要考虑其外部性,即控制转移的修改会导致其后续执行的一系列活动均不同。然而,此时的行为控制仅是控制单一的活动,因此,仅从对栈的影响来看,这条指令影响的是PC寄存器的计算,而PC寄存器是变化最频繁的寄存器——每一条指令的执行,都会使的PC寄存器发生变化。控制转移指令的增加、删除、修改的操作很难与活动执行对应,因此,对于控制转移指令,本发明不定义任何操作。
算术运算:算术运算活动的效果是对栈中的某些寄存器进行算术运算。算术指令可视为对某一寄存器进行赋值。例如:add-int/2addr Reg1Reg2在运行时所对应的活动意味着对寄存器Reg1进行了赋值,赋值的结果为该寄存器与Reg2寄存器的值之和。对该活动的增加、删除、修改操作可实现为对目标寄存器的控制:Add的含意就是增加一个对该活动所赋值的寄存器进行进一步赋值;Delete的含意就是消除该寄存器赋值的效果,即将该寄存器的值恢复;Transform的含意就是对被修改的活动所影响的寄存器的赋值。Add、Delete和Transform都需要应用到达S'状态时该活动所对应的方法仍未执行完毕。如果方法已经执行完毕,方法栈已经销毁,也就不存在该寄存器。
字段读取:字段读取活动影响的内存区域是栈。字段读取活动对内存的影响是读取堆中的某个对象的某个字段,并写到特定寄存器里。因此,这类活动的增加、删除、修改的语义与算术运算活动相同。
数组读取:数组读取活动与字段读取活动接近,对内存的影响是从堆中的某个数组中读取某个元素,并写到某个寄存器上。因此,这类活动的增加、删除、修改的语义与算术运算活动相同。
类实例化:该类型的活动影响的内存区域是堆。Java编程语言中,类实例化活动对应的指令为new-instance。不论是Java的.class格式的字节码还是dex格式的字节码,类的实例化均分为两条指令:一为new-instance,二为调用其对应的构造函数。对于类实例化活动,增加(Add)的语义则是新增一个同样类型的对象;修改的语义无定义;删除的语义则是消除这个对象,也就是强制回收该对象。对于存在别的对象引用它的情况,则可实现为将引用它的对象的相应字段赋值为空。
数组实例化:该类型的活动的增、删改的语义与类实例化相同。
字段赋值:该类型的活动影响的内存区域为堆。字段赋值就是读取某个寄存器的值,并写到堆中的某个对象的某个字段中。因此,这类活动的增加(Add)意味着新增一个活动,该活动为对某个对象的某个字段的赋值;Delete意味着消除本次写活动的影响,即将其赋值为之前的值;而Transform则是对某个对象的某个字段的修改。
数组赋值:与字段赋值相似,其增加、删除、修改的语义与字段赋值一致。
线程同步:虽然该类型的活动会影响线程之间的执行次序,但该类型的活动既不直接影响栈区,也不影响堆区。因此,从内存控制等价的角度,对于线程同步本发明不定义任何操作。
垃圾回收:垃圾回收活动是对堆区产生影响的活动。具体地,有分为回收对象活动和压缩对象活动。对于回收对象活动,Add意味着对一个对象进行回收,与NewInstance的Delete所实现的控制一样,是强制对该对象回收,对于存在引用的情况则赋值为空。Delete则意味着对象实例化,并且,将该对象的状态恢复至刚回收时刻的状态。回收对象活动的Transform操作无定义。对于对象压缩活动,该活动的效果是将一个对象由地址1移至地址2。从编程语言的角度上看,这个压缩活动对开发者是完全透明的;有的虚拟机甚至可以不实现带压缩活动的垃圾回收算法。因此对于压缩活动,其三种操作无定义。
方法调用:相比于上述的活动,方法调用活动是较复杂的。方法调用活动是一个包含一系列活动的活动。因此,它不仅会对栈区产生影响,还可能对堆区数据产生影响。方法调用活动的Add操作意味着再执行一次方法调用;Delete则意味着消除方法调用的影响。对于已经执行结束的方法调用,Delete意味着同时消除该方法所包含的堆区相关的活动;而Transform则难以定义。1)如果定义为在新的上下文环境重新执行一次方法调用,则重新执行的方法调用的序列难以与!'保持内存控制等价的关系。2)如果定义为对直接对参数所对应的寄存器和栈进行修改,则很难在基于寄存器的dex字节码上和基于操作栈的.class格式字节码上保持一致。因此,对于方法调用不定义Transform操作。
类加载:类加载活动对应于ClassLinker的一组初始化活动及相关类的<clinit>方法的执行。与普通的方法调用不同,类加载所引起的<clinit>只会被调用一次。因此,其Add操作无定义。而Delete着意味着类卸载,本发明将其定义为执行所有属于这个类的对象的Add操作,并消除该类在ClassLinker的影响。
(2)结构式控制
结构式控制意味着对运行时活动的修改会反映到原应用的代码段中。即结构式控制将应用行为运行时模型当作一段执行过的代码片段,对行为运行时模型的增加、删除、修改操作,则体现为对代码片段的增加、删除、修改。
在本发明实施例中,对所述终端应用行为进行结构式控制的步骤包括:
获取终端应用行为的运行时模型M,一组操作以及一个转换后的活动序列A';
将所述一组操作映射为一段目标代码,以使所述目标代码的执行所产生的活动序列A”与活动序列A'保持控制等价关系。
对于任一给定的一个行为运行时模型片段,它由一组方法调用、字段读写等活动组成。每一个活动均可通过程序分析的方法自动生成相应的代码片段,和原片段保持堆控制等价。
上述步骤中,针对任意活动,将所述一组操作映射为一段目标代码的步骤包括:获取数据依赖,使得所述活动执行的数据依赖与活动发生时刻相同;
将所述活动转换为相应的目标代码。
在本发明实施例中,所述数据依赖包括数值类型和对象类型;
对于一个活动,当其依赖的数据类型为数值类型时,直接采用运行时模型中活动执行时对应的数值;
对于一个活动,当其依赖的数据类型为对象类型时,分为局部对象和全局对象;其中,当其依赖的数据类型为局部对象时,通过回放与该对象相关活动的方式生成构造所述局部对象的代码;当其依赖的数据类型为全局对象时,通过程序分析构造出一组可达的对象引用链以获取该对象,根据对象之间的引用类型,自动生成动态数据依赖相关的代码。
本发明实施例中的局部对象是在功能执行过程中实例化出来的对象,并且在功能执行结束后会被垃圾回收的对象。针对所述局部对象的构造,包括基于活动序列构造的局部对象构造和基于运行时堆模型的局部对象构造;下面以运行时堆模型为例进行阐述:
对于基于活动序列的局部对象构造:
通过求解活动序列中某一个对象的堆控制等价序列的算法,其输入为一个包含一组活动序列控制流f和一个相关对象。首先判断当前控制流节点是否与该对象相关,如果不相关则直接返回空。如果相关,则构造一个数组resut以保存堆控制等价的活动序列。其次,第一个等价的活动序列就是该控制流的最外层活动。例如,当前控制流是一个方法调用,那么直接再执行一次相同的方法调用,相应对象的状态就堆控制等价。除此以外,如果该控制流是一个方法调用,那么堆控制等价的活动序列还包括其子控制流的堆等价序列的笛卡尔积。求子控制流的堆控制等价序列可视为进行函数内联的过程。对一组平均子控制流个数为K,平均深度为H的控制流而言,其堆控制等价序列个数为O(KH)。
对于基于运行时堆模型的局部对象构造:
基于运行时堆模型中的初始Snapshot和所有堆操作活动序列DataActions,可实现查询任意时刻的该对象的状态。首先是加载初始镜像和活动,步骤如下:
读入初始镜像,由此获得一个初始的Snapshot,在初始的Snapshot中,每个对象都以当时运行时内存地址的标识。
遍历所有活动:对于实例化活动,依次在初始的Snapshot中添加相应的对象;对于修改活动和清除活动,将其添加至相关对象的活动序列中;对于压缩活动,除了添加至至相关对象的序列中之外,再创建一个以压缩后地址为标识的对象,并将该压缩活动作为该新建对象的首个活动。
通过以上两步可以保证所有在该过程出现的对象,都在的Snapshot中。其中,由于压缩活动、回收活动、再分配活动,可能导致某个内存地址对应于多个对象。因此,在Snapshot中以标识和创建时间作为一个对象的全局标识符。
在加载完毕后,可实现任意对象的任意时候的状态查询。要查询某一时刻某一对象的状态,就是查询该对象在该时刻的每个字段的值。对于数值类型的字段而言,该时刻的值就是离该时刻最近的一次修改操作的值;而对于对象类型的字段,则是当时所引用的对象的地址在该时刻的值。因此,算法的核心是,根据对象中每一字段的活动,查询该时刻的值。首先,将一个对象相关的所有活动分配至每个字段,然后通过二分查询实现查找按时间顺序排序的活动序列中最接近该时刻的活动。令DataActionCount为某对象的某字段相关的活动,ObjectCount为对象数量,FieldCount为类的平均字段数量。则平均上看有:
因此,算法的复杂度为每个字段进行log(DataActionCount)次数的查询,即,算法的复杂度为:O(FieldCount*log(DataActionCount))。本算法与活动数量的对数成正比,因此可以在活动数量巨大时保持检索的效率。
对比上述两种生成局部依赖的方式,从执行效率上看,第二种更高——它相当于是仅将与所需对象相关的字段写操作回放执行一遍;从可读性上来看,基于活动序列的局部对象构造可以产生行数较少的代码。
在本发明实施例中,所述全局对象根据运行时堆模型中的引用链获得。
基于引用链的全局对象引用获取方法:全局对象就是在功能执行前后,该对象堆存在于堆中。全局对象可通过两种方式获得:
根据运行时堆模型中的引用链获得或者利用前述算法,以该全局对象为相关对象,生成相应的模型片段。由于该对象为全局对象,在原有执行逻辑中可能存在某个数据依赖较少,甚至没有数据依赖的方法可直接获取该全局对象。因此,只需筛选生成的相应的模型片段中元素个数较少的片段。
根据对象的依赖关系,选择好若干个对象在若干控制流中的模型片段,即可通过本方法自动生成相应代码片段。根据生成的代码片段进行一定的编辑,即可实现利用本发明的结构式控制完成对应用行为修改。
下面,采用一具体实例验证本发明实施例对终端应用行为控制的有效性。
针对移动互联网中广泛使用的安卓移动应用,给出行为反射框架的原型***实现:Reflectall。Reflectall的全称为Reflection at low level interpreter,具有两重含意,一是基于底层的行为解释器实现的反射;二是它可以监测和控制指令级别的应用行为。Reflectall基于安卓操作***开源项目。为了实现移动应用行为的监测与控制,Reflectall平台可分为行为运行时模型构造子***、模型分析与代码生成子***和运行子***,实现了行为反射框架中的监测和控制。
参照图7,为Reflectall模型生成子***架构示意图。Reflectall的行为运行时模型构造子***实现了移动应用行为运行时模型的构造,其核心实现在***层,由优化-反优化器、行为解释器、模型构建和接口层四个模块组成。这个四个模块实现了移动应用行为的监测与控制。
其中,优化-反优化器:安卓运行时环境可加载CPU可直接执行的原生指令。因此,需要将以原生指令切换为字节码,即反优化,并通过行为解释器进行解释执行,从而实现对移动应用运行时活动的监测。移动应用由于其复杂性,难以监测移动应用执行中的所有活动,因此引入了一个两级筛选机制。优化-反优化器实现了两级筛选机制中的类筛选机制,通过优化-反优化器,可以按需地将待监测的类反优化为字节码,并进行解释执行;而对于未被监测的类,则仍然在原生执行器中执行。优化-反优化器会在如下三种情况下触发:1)收到开始监测的命令时,会根据所配置的参数,对当前已经加载的类的方法进行筛选,并进行反优化;2)收到结束监测命令时,会对当前已反优化后的类进行再优化,令其重新进入原生执行器中执行;3)类链接器加载新的类时,会对类进行类似于情况1)中的筛选和反优化过程。为了保证程序执行的正确性,反优化的过程需要和部分垃圾回收算法一样,暂时挂起所有线程的执行,待反优化执行结束后,再恢复线程的执行。通过这种局部反优化,并保持解释执行与原生执行共存的状态,可以大大减少监测的性能开销。
行为解释器:行为解释器是解释执行dex格式字节码的解释器,能在解释执行的过程中,监测当前的程序执行中发生的活动。移动应用行为运行时模型中的活动大多是由行为解释器生成。除了行为解释器所生成的活动,垃圾回收器也可以生成部分活动——垃圾回收活动。行为解释器还实现了两级筛选机制中的活动筛选机制,可根据配置的活动收集粒度产生不同种类的活动。
模型构建器:行为解释器与垃圾回收器所产生的活动会在模型构建器中构建。当运行时产生的活动较多时,会导致内存占用较大。因此,模型构建器实现了在线和离线的模型构建。当活动较少时,模型构建器运行于在线的模型构建模式时,当活动数量达到配置的阀值,模型构建器会将当前已产生的活动序列持久化,并以文件的形式持久化至存储。
接口层:对优化-反优化器、行为解释器和模型构建器所提供的功能进行封装。同时也提供反序列化活动所需的接口,例如根据地址查找对象和给定对象转换为地址等。
本发明实例所实现的原型中,可以生成两种移动应用行为运行时模型:1)包含了运行时数据依赖的精细化模型;2)不包含运行时数据依赖的精简模型。基于***层的实现,在框架层,Reflectall包括一组行为反射接口,可监测不同粒度的应用的活动,生成不同粒度的应用行为运行时模型;一组远程调试连接接口,可控制应用活动监测的开始与结束。在应用层,对框架层的接口进行封装,实现了一个安卓应用,可以以Web服务的形式对外提供远程调试接口。
Reflectall的分析与代码生成子***为浏览器-服务端架构。分析与代码生成子***实现了:
版本管理:利用git管理不同版本的移动应用与互操作接口。同时支持服务器端编译,并利用客户端的接口管理应用将编译好的dex字节码推送至客户端。
栈模型可视化:提供了一个树状的视图,并支持基于关键字的数据依赖沾染分析。
Reflectall的接口运行子***在安卓开源项目的框架层上添加了一个行为反射类加载器,如图8所示,为本发明示例Reflectall的接口运行子***的结构示意图。当应用进程启动时,会检查是否有可加载的行为反射接口字节码文件。如果存在适合当前应用的行为反射接口字节码文件,则通过行为反射类加载器将其加载进应用进程,同时,利用Binder通信机制向接口管理应用注册当前应用提供的互操作接口。接口管理应用提供了接口转发、状态检测等服务。调用者进程通过接口管理应用可实现与指定应用互操作。
本发明以一个包含69个开源安卓应用的开源应用集和一个包含39个闭源应用的闭源应用集对Reflectall模型生成的性能进行验证。具体验证时,本发明以Reflectall模型所述的面向用户的图形界面接口转换为面向互操作的接口算法作为结构式控制的应用示例,在闭源应用集中的其中35个应用中进行实验。最后,给出一个基于行为式控制实现在不对原应用的代码进行修改的情况下,实现应用状态的实时修改的示例。
结构式控制示例
本发明示例在闭源应用集中的选取了35个应用,针对不同应用提供的功能,制定好了待开发的接口,总共150个互操作接口。接口的开发人员共计四名,Java开发经验1年至3年不等。在进行为期两周的Reflectall使用培训后,开始进行接口开发。各个应用对应的接口数量和工作量(以人天为单位)由于数量较大,暂不在本文列出。
从上述实验中,发现:
(1)互操作接口的开发时间由0.5人天至5天人不等。其中,工作量最大的那个接口是由于涉及了三个应用进程,执行逻辑较为复杂。
(2)对于同一个应用的不同功能,往往存在模式相似的现象,因此,对于同一个应用中,这些执行模式相似的接口,往往后续接口的开发工作量要远小于第一个接口的开发工作量。
(3)利用Reflectall所抽象的应用行为运行时模型,应用开发人员可以在完全不了解应用、没有文档和代码的情况,快速地实现互操作接口,每个接口的平均开发量为1.5人天。
行为式控制示例
如前文所述,行为式控制实现的是在不重启应用、不对应用进行重新编译,只基于运行时行为反射接口,就实现对原应用的监测与控制。在本发明示例中,以一个安卓计算器应用作为示例,详细介绍如何利用本文所实现的行为反射接口的行为式控制,实现对计算器使用过程中的表达式的记录和回放。
该计算器的原始类图如9(a)所示。类MainActivity表示计算器的主界面,在主界面中,除了一系列数字和计算符的按钮外,还有一个显示当前表达式的文本框CalculatorEditText(editText字段)。如果不基于本文所述的行为反射接口,而利用AspectJ将正交于计算器计算逻辑的表达式监测与修改逻辑在编译时编织进原应用,需要做如下的修改:
开发人员需要实现一个监控类ExpressionRecorder,并在MainActivity中新增一个字段,为ExpresionRecorder类型。要实现对运行时表达式的监测,开发人员需要定义一个切面:该切面为editText的onTextChanged方法的执行前;在该切面执行的逻辑为,记录onTextChanged方法的参数。对所记录的序列进行整理,由于onTextChanged在每一次表达式变化时都会被调用,例如,输入1+1时,该方法会被调用3次。为了便于显示,开发人员需要实现将监测到的多个表达式进行子串的筛选,实现表达式重复子串的过滤。即,对于某个表达式,如果是另一个表达式的子串,则过滤。在记录了onTextChanged所执行的方法后,开发人员通过理解代码,在ExpressionRecorder中编写一个调用editText的setText方法,实现对界面上表达式状态的修改。最后,对ExpressionRecorder所记录的表达式进行可视化,三个按钮,分别起到开始记录表达式、停止记录表达式和将当前表达式修改为之前记录的某个表达式的功能。
在进行上述的修改后,开发人员将AspectJ的编译流程配置至原应用的编译流程中,进行编译并生成新的计算器应用。修改后的类图如9(b)所示。可以发现,开发人员定义的切面实际上引入的是CalculatorEditText与ExpressionRecorder的耦合——在CalculatorEditText的执行流程中,添加了将表达式记录到ExpressionRecorder的逻辑。
而基于本发明控制提供的行为反射接口,只需要做如下修改:
开发人员需要实现一个监控类ExpressionRecorder。要实现对运行时表达式的监测,只需要调用行为反射接口的模型生成功能,其中配置好类筛选器为CalculatorEditText。筛选模型中的活动,实现表达式重复子串的过滤。通过模型的Add操作,添加一个setText的活动,实现对界面表达式的修改功能。最后,对ExpressionRecorder所记录的表达式进行同上的可视化。
基于本发明所述的远程接口,对应用运行时状态的监测和修改的运行逻辑不需要与原应用运行于同一进程中,因此,该部分逻辑可以剥离出来,单独编译为一个原计算器应用的插件。
相比本发明所述的方法,基于AspectJ的方法需要:
第1步,修改原应用,新增加MainActivity与ExpressionRecorder的耦合。
第2步,修改源应用的编译流程,将正交于原应用的业务功能的代码编织到原应用中。
实际上,第2步中也就意味着在代码中建立CalculatorEditText与ExpressionRecorder的耦合。而本发明的实现方式,则是利用行为反射接口,真正地把ExpressionRecorder实现的监测逻辑与原应用的功能剥离开来,耦合程度更低。同时,利用本发明所述的行为反射接口的开发流程会更简单。
综上,本发明在终端应用行为控制方面,基于Reflectall指令级的控制,成功的将微博、京东在内的复杂的闭源应用中150个面向用户的功能自动化地转换为应用可编程接口,总共耗时225天,平均耗时1.5人/天,展示了Reflectall在实现移动应用按需互操作上的有效性。
上述实施例仅为优选实施例,并不用以限制本发明的保护范围,在本发明的精神和原则之内所作的任何修改、等同替换和改进等,均应包含在本发明的保护范围之内。
Claims (10)
1.一种基于运行时模型实现对终端应用控制的方法,其特征在于,所述运行时模型包括运行时栈模型和运行时堆模型,包括:
预定义对所述运行时模型的操作以及模型片段在堆、栈区域影响的等价性;
对所述运行时模型保持所述等价性进行转换,对所述运行时模型进行分解,得到一组可操作的模型片段;
根据分解后的模型片段,建立所述运行时模型与应用状态和应用代码的因果关联,以对所述终端应用行为进行控制。
2.如权利要求1所述的方法,其特征在于,所述运行时模型包括一段时间内发生的一组具有逻辑关联的活动的集合;
所述预定义对所述运行时模型的操作包括:
增加,用于在原有活动执行流程中增加一部分程序活动;
删除,用于消除原有活动执行流程中执行的活动对程序本身的影响;
修改,用于在消除原有活动的影响后,重新执行修改的活动。
3.如权利要求1所述的方法,其特征在于,对所述终端应用行为进行控制包括对所述终端应用行为进行行为式控制和/或结构式控制。
4.如权利要求3所述的方法,其特征在于,对所述终端应用行为进行行为式控制的步骤包括:
设终端应用的内存初始状态S,活动序列A;
经过一段时间的执行,获取运行后的内存状态为S·A=S',对所述运行时模型保持所述等价性进行转换后的活动序列为A',得到目标状态为S·A′=S″;
利用S·A′=(S·A)·A″=S′·A″求解增量活动序列A″,使得A+A″=A′,完成对所述终端应用行为进行行为式控制的过程。
5.如权利要求4所述的方法,其特征在于,所述增量活动序列A″包括:控制转移、算术运算、字段读取、数组读取、类实例化、数组实例化,字段赋值、数组赋值、线程同步、垃圾回收、方法调用和类加载。
6.如权利要求3所述的方法,其特征在于,对所述终端应用行为进行结构式控制的步骤包括:
获取终端应用行为的运行时模型M,一组操作以及一个转换后的活动序列A′;
将所述一组操作映射为一段目标代码,以使所述目标代码的执行所产生的活动序列A″与活动序列A′保持控制等价关系。
7.如权利要求6所述的方法,其特征在于,针对任意活动,将所述一组操作映射为一段目标代码的步骤包括:
获取数据依赖,使得所述活动执行的数据依赖与活动发生时刻相同;
将所述活动转换为相应的目标代码。
8.如权利要求7所述的方法,其特征在于,所述数据依赖包括数值类型和对象类型;
对于一个活动,当其依赖的数据类型为数值类型时,直接采用运行时模型中活动执行时对应的数值;
对于一个活动,当其依赖的数据类型为对象类型时,分为局部对象和全局对象;其中,当其依赖的数据类型为局部对象时,通过回放与该对象相关活动的方式生成构造所述局部对象的代码;当其依赖的数据类型为全局对象时,通过程序分析构造出一组可达的对象引用链以获取该对象,根据对象之间的引用类型,自动生成动态数据依赖相关的代码。
9.如权利要求8所述的方法,其特征在于,针对所述局部对象的构造,包括基于活动序列构造的局部对象构造和基于运行时堆模型的局部对象构造。
10.如权利要求8所述的方法,其特征在于,所述全局对象根据运行时堆模型中的引用链获得。
Priority Applications (2)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN201910498732.0A CN110362363B (zh) | 2019-06-10 | 2019-06-10 | 一种基于运行时模型实现对终端应用控制的方法 |
PCT/CN2019/119271 WO2020248511A1 (zh) | 2019-06-10 | 2019-11-18 | 一种基于运行时模型实现对终端应用控制的方法 |
Applications Claiming Priority (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN201910498732.0A CN110362363B (zh) | 2019-06-10 | 2019-06-10 | 一种基于运行时模型实现对终端应用控制的方法 |
Publications (2)
Publication Number | Publication Date |
---|---|
CN110362363A CN110362363A (zh) | 2019-10-22 |
CN110362363B true CN110362363B (zh) | 2021-03-12 |
Family
ID=68216893
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
CN201910498732.0A Active CN110362363B (zh) | 2019-06-10 | 2019-06-10 | 一种基于运行时模型实现对终端应用控制的方法 |
Country Status (2)
Country | Link |
---|---|
CN (1) | CN110362363B (zh) |
WO (1) | WO2020248511A1 (zh) |
Families Citing this family (6)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN110347448B (zh) * | 2019-06-10 | 2021-02-12 | 北京大学 | 一种构造终端应用行为的运行时模型的方法 |
CN110362363B (zh) * | 2019-06-10 | 2021-03-12 | 北京大学 | 一种基于运行时模型实现对终端应用控制的方法 |
CN111552524B (zh) * | 2020-05-06 | 2023-10-13 | Oppo(重庆)智能科技有限公司 | 一种插件加载方法、装置及计算机可读存储介质 |
CN111953686B (zh) * | 2020-08-12 | 2022-11-29 | 浙江互灵科技有限公司 | 一种应用于智能化基站的多协议自适应方法 |
CN111966429B (zh) * | 2020-08-21 | 2022-07-08 | 支付宝(杭州)信息技术有限公司 | 小程序处理方法及装置 |
CN116975159B (zh) * | 2023-09-25 | 2024-02-23 | 云筑信息科技(成都)有限公司 | 一种增量数据同步的处理方法 |
Family Cites Families (7)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN103473400B (zh) * | 2013-08-27 | 2016-12-28 | 北京航空航天大学 | 基于层次依赖建模的软件fmea方法 |
US9389890B2 (en) * | 2014-03-27 | 2016-07-12 | Microsoft Technology Licensing, Llc | Hierarchical directives-based management of runtime behaviors |
CN109189374B (zh) * | 2018-06-22 | 2020-08-28 | 北京大学 | 基于对象引用链的对象构造代码生成方法及*** |
CN109240666B (zh) * | 2018-06-22 | 2020-08-25 | 北京大学 | 基于调用栈和依赖路径的函数调用代码生成方法及*** |
CN109189469B (zh) * | 2018-06-22 | 2020-08-28 | 北京大学 | 基于反射的安卓应用微服务化方法及*** |
CN110362301B (zh) * | 2019-06-10 | 2021-04-09 | 北京大学 | 一种终端应用行为反射的处理方法 |
CN110362363B (zh) * | 2019-06-10 | 2021-03-12 | 北京大学 | 一种基于运行时模型实现对终端应用控制的方法 |
-
2019
- 2019-06-10 CN CN201910498732.0A patent/CN110362363B/zh active Active
- 2019-11-18 WO PCT/CN2019/119271 patent/WO2020248511A1/zh active Application Filing
Also Published As
Publication number | Publication date |
---|---|
WO2020248511A1 (zh) | 2020-12-17 |
CN110362363A (zh) | 2019-10-22 |
WO2020248511A9 (zh) | 2021-02-11 |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
CN110362363B (zh) | 一种基于运行时模型实现对终端应用控制的方法 | |
CN110362301B (zh) | 一种终端应用行为反射的处理方法 | |
Karmani et al. | Actor frameworks for the JVM platform: a comparative analysis | |
US7281248B2 (en) | Virtualized and realized user interface controls | |
EP2671161B1 (en) | System and method for determining an objects lifetime in an object oriented environment | |
US20130227536A1 (en) | Increasing Performance at Runtime from Trace Data | |
CN110851237B (zh) | 一种面向国产平台的容器跨异构集群重构方法 | |
US20140047222A1 (en) | Method and device for recombining runtime instruction | |
Satoh | A framework for data processing at the edges of networks | |
Johnsen et al. | Dynamic resource reallocation between deployment components | |
Cicotti | Tarragon: a programming model for latency-hiding scientific computations | |
CN110347448B (zh) | 一种构造终端应用行为的运行时模型的方法 | |
Shan et al. | KubeAdaptor: a docking framework for workflow containerization on Kubernetes | |
Suzumura et al. | ScaleGraph: A high-performance library for billion-scale graph analytics | |
Franchi | A domain specific language approach for agent-based social network modeling | |
Shahverdi et al. | Comparative evaluation for the performance of big stream processing systems | |
Sun et al. | Non-MapReduce computing for intelligent big data analysis | |
Ryan et al. | Application adaptation through transparent and portable object mobility in java | |
Gherari et al. | A smart mobile cloud environment for modelling and simulation of mobile cloud applications | |
Ricci et al. | From actors and concurrent objects to agent-oriented programming in simpAL | |
Tasneem et al. | Android memory optimization | |
McNabb et al. | Mrs: Mapreduce for scientific computing in python | |
Jalalian et al. | Autonomous task scheduling for fast Big Data processing | |
Satoh | Mapreduce processing on IoT clouds | |
Wang et al. | Reusing garbage data for efficient workflow computation |
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 |