掌桥专利:专业的专利平台
掌桥专利
首页

一种性能统计方法和装置

文献发布时间:2023-06-19 13:49:36


一种性能统计方法和装置

技术领域

本发明涉及安卓程序性能分析技术领域,具体涉及一种性能统计方法和装置。

背景技术

在安卓系统的APP程序中,SO层通常用来存放具有较大计算量需求的功能API接口,当开发者需要了解该程序的性能时,需要统计出SO层中每个API接口的调用情况。

但是,SO层采用C语言或C++语言进行编写,因此java层需要通过jni层来调用SO层提供的API接口。为方便java层的调用,jni层提供了丰富的调用方式,因此SO层存在多种API接口参数参与相关调用,不同的参数之间无法直接比较数据的大小,使得无法准确高效地对SO层API接口进行性能统计。

发明内容

本发明提供一种性能统计方法和装置,以准确高效地对SO层API接口进行性能统计。

为实现上述目的,本发明实施例提供了以下方案:

第一方面,本发明实施例提供一种性能统计方法,包括:

获取第一线程当前调用的SO层API接口的接口参数;

将所述接口参数转化为byte数据;

根据所述byte数据,构建一维数组;

调用NewDirectByteBuffer函数,将所述一维数组存储在C++存储内存中;

创建env变量,并将所述env变量存储在所述第一线程的线程局部存储变量中;

将所述env变量赋值为所述C++存储内存的值;

将所述C++存储内存转换为java存储内存;

根据所述java存储内存,获取所述一维数组;

根据所述一维数组,获取所述SO层API接口的接口参数中的性能统计数据;

根据所述性能统计数据,调用统计线程,进行所述SO层API接口的性能统计;

所述将所述接口参数转化为byte数据,包括:

确定所述接口参数的数据类型;

若所述接口参数的数据类型为int数据,则将所述接口参数转化为由4个字节组成的第一byte数据;

若所述接口参数的数据类型为string数据,则将所述接口参数转化为第二byte数据;

若所述接口参数的数据类型为list数据,则先将所述接口参数转化为若干个string数据,再将所述若干个string数据转化为第三byte数据;

若所述接口参数的数据类型为map数据,则先将所述接口参数的key值和value值分别转化为byte数据格式,再将byte数据格式的所述key值和所述value值拼接为第四byte数据。

在一种可能的实施例中,所述创建env变量,并将所述env变量存储在所述第一线程的线程局部存储变量中,包括:

调用虚拟机接口,创建所述env变量;

创建第一变量和第一变量释放监测函数;

根据所述第一变量和所述第一变量释放检测函数,调用pthread_key_create函数,创建所述第一线程的所述线程局部存储变量;

将所述env变量存储在所述线程局部存储变量中。

在一种可能的实施例中,所述将所述C++存储内存转换为java存储内存,包括:

创建一维数组封装类;

将所述C++存储内存及其长度存储进所述一维数组封装类中;

将所述C++存储内存的控制权转入到所述一维数组封装类中;

利用move操作,调用所述C++存储内存的控制权,将所述C++存储内存赋值给成员变量;

根据所述成员变量,调用所述NewDirectByteBuffer函数,将所述C++存储内存转换为所述java存储内存。

在一种可能的实施例中,所述将所述C++存储内存转换为java存储内存之后,所述方法还包括:

创建生命周期控制模板类;

将访问jni接口的参数作为第一成员变量;

创建jobject类型的第二成员变量;

创建string类型的函数名变量;

根据所述第一成员变量、所述第二成员变量和所述函数名变量,将所述生命周期控制模板类实例化,获得生命周期控制构造函数;

将所述第一成员变量赋值为所述env变量;

将所述第二成员变量赋值为所述一维数组封装类的对象实例。

在一种可能的实施例中,所述根据所述性能统计数据,调用统计线程,进行所述SO层API接口的性能统计,包括:

创建传输队列;

将所述性能统计数据存储在所述传输队列中;

利用所述上传队列,在所述统计线程空闲时,将所述性能统计数据传输至所述统计线程中,进行所述SO层API接口的性能统计。

第二方面,本发明实施例提供一种性能统计装置,包括:

接口参数获取模块,用于获取第一线程当前调用的SO层API接口的接口参数;

数据转化模块,用于将所述接口参数转化为byte数据;

一维数组构建模块,用于根据所述byte数据,构建一维数组;

内存分配模块,用于调用NewDirectByteBuffer函数,将所述一维数组存储在C++存储内存中;

env变量创建模块,用于创建env变量,并将所述env变量存储在所述第一线程的线程局部存储变量中;

第一赋值模块,用于将所述env变量赋值为所述C++存储内存的值;

内存转换模块,用于将所述C++存储内存转换为java存储内存;

一维数组获取模块,用于根据所述java存储内存,获取所述一维数组;

性能统计数据获取模块,用于根据所述一维数组,获取所述SO层API接口的接口参数中的性能统计数据;

性能统计模块,用于根据所述性能统计数据,调用统计线程,进行所述SO层API接口的性能统计;

所述数据转化模块,包括:

数据类型确定模块,用于确定所述接口参数的数据类型;

第一转化模块,用于在所述接口参数的数据类型为int数据时,将所述接口参数转化为由4个字节组成的第一byte数据;

第二转化模块,用于在所述接口参数的数据类型为string数据时,将所述接口参数转化为第二byte数据;

第三转化模块,用于在所述接口参数的数据类型为list数据时,先将所述接口参数转化为若干个string数据,再将所述若干个string数据转化为第三byte数据;

第四转化模块,用于在所述接口参数的数据类型为map数据时,先将所述接口参数的key值和value值分别转化为byte数据格式,再将byte数据格式的所述key值和所述value值拼接为第四byte数据。

在一种可能的实施例中,所述env变量创建模块,包括:

第一创建模块,用于调用虚拟机接口,创建所述env变量;

第二创建模块,用于创建第一变量和第一变量释放监测函数;

第三创建模块,用于根据所述第一变量和所述第一变量释放检测函数,调用pthread_key_create函数,创建所述第一线程的所述线程局部存储变量;

env变量存储模块,用于将所述env变量存储在所述线程局部存储变量中。

在一种可能的实施例中,所述内存转换模块,包括:

一维数组封装类创建模块,用于创建一维数组封装类;

第一存储模块,用于将所述C++存储内存及其长度存储进所述一维数组封装类中;

控制权转入模块,用于将所述C++存储内存的控制权转入到所述一维数组封装类中;

第二赋值模块,用于利用move操作,调用所述C++存储内存的控制权,将所述C++存储内存赋值给成员变量;

转换模块,用于根据所述成员变量,调用所述NewDirectByteBuffer函数,将所述C++存储内存转换为所述java存储内存。

在一种可能的实施例中,所述装置还包括:

生命周期控制模板类创建模块,用于创建生命周期控制模板类;

第四创建模块,用于将访问jni接口的参数作为第一成员变量;

第五创建模块,用于创建jobject类型的第二成员变量;

第六创建模块,用于创建string类型的函数名变量;

构造函数获取模块,用于根据所述第一成员变量、所述第二成员变量和所述函数名变量,将所述生命周期控制模板类实例化,获得生命周期控制构造函数;

第三赋值模块,用于将所述第一成员变量赋值为所述env变量;

第四赋值模块,用于将所述第二成员变量赋值为所述一维数组封装类的对象实例。

在一种可能的实施例中,所述性能统计模块,包括:

第七创建模块,用于创建传输队列;

统计数据存储模块,用于将所述性能统计数据存储在所述传输队列中;

统计模块,用于利用所述上传队列,在所述统计线程空闲时,将所述性能统计数据传输至所述统计线程中,进行所述SO层API接口的性能统计。

第三方面,本发明实施例提供一种计算机设备,包括:

存储器,用于存储计算机程序;

处理器,用于执行该计算机程序以实现如上述第一方面任意一项所述的性能统计方法的步骤。

第四方面,本发明实施例提供一种计算机可读存储介质,其上存储有计算机程序,该计算机程序被处理器执行时以实现如上述第一方面任意一项所述的性能统计方法的步骤。

本发明与现有技术相比,具有如下的优点和有益效果:

本发明先将获取到的API接口参数转化为byte数据,并构建一维数组,之后为该一维数组分配了连续的内存空间,从而在SO层向java层传输时,利用NewDirectByteBuffer函数,通过整块内存空间进行数据传输,提高了数据的传输效率,从而能够准确高效地对SO层API接口进行性能统计。

附图说明

为了更清楚地说明本说明书实施例或现有技术中的技术方案,下面将对实施例中所需要使用的附图作简单地介绍,显而易见地,下面描述中的附图仅仅是本说明书的一些实施例,对于本领域普通技术人员来讲,在不付出创造性劳动的前提下,还可以根据这些附图获得其他的附图。

图1是本发明实施例提供的一种性能统计方法的流程图;

图2是本发明实施例提供的一种性能统计装置的结构示意图。

具体实施方式

下面将结合本发明实施例中的附图,对本发明实施例中的技术方案进行清楚、完整的描述,显然,所描述的实施例仅仅是本发明一部分实施例,而不是全部的实施例,基于本发明实施例,本领域普通技术人员所获得的所有其他实施例,都属于本发明实施例保护的范围。

请参阅图1,图1为本发明实施例提供的一种性能统计方法的流程图,具体包括步骤101至步骤110。

步骤101,获取第一线程当前调用的SO层API接口的接口参数。

本步骤的目的是:获取性能统计需要用到的相关参数。

具体的,第一线程是当前java层中某个调用者用来调用SO层中的某个或某些API接口的,以通过接口调用实现一些具体的功能(例如指令转换、发起通知和打开摄像头等)。

当第一线程调用SO层API接口时,本步骤就特意留下这些被调用API接口的接口参数。

步骤102,将所述接口参数转化为byte数据。

本步骤的目的是:为了之后将不同类型的接口参数同时存放在同一内存空间以提高传输效率的步骤做准备。

具体的,由于java层中的数据类型是jbyteArray的类型,而在SO层中的C++对应的数据类型的char*类型,两者的数据都是以一个字节(byte)为单位,因此通过本步骤的数据类型转换,接口参数在java层中jbyteArray的数据编码格式在SO层中的char*的数据编码格式是一一匹配的,方便之后进行性能统计。

这里,本发明还提供了一种较优的接口参数转化方案,具体方案为:

所述将所述接口参数转化为byte数据,包括步骤21至步骤25。

步骤21,确定所述接口参数的数据类型。

本步骤的目的是:确定出参数类型,以方便之后针对不同的参数类型进行数据转换。

具体的,API接口的接口参数常见的数据类型有int、string、list和map等,每种类型的数据都有其相应的数据声明,通过该声明,就能够很容易确定出接口参数的数据类型。

步骤22,若所述接口参数的数据类型为int数据,则将所述接口参数转化为由4个字节组成的第一byte数据。

本步骤的目的是:提供一种将隶属于int数据的接口参数转换为byte数据的方案。

步骤23,若所述接口参数的数据类型为string数据,则将所述接口参数转化为第二byte数据。

本步骤的目的是:提供一种将隶属于string数据的接口参数转换为byte数据的方案。

步骤24,若所述接口参数的数据类型为list数据,则先将所述接口参数转化为若干个string数据,再将所述若干个string数据转化为第三byte数据。

本步骤的目的是:提供一种将隶属于list数据的接口参数转换为byte数据的方案。

步骤25,若所述接口参数的数据类型为map数据,则先将所述接口参数的key值和value值分别转化为byte数据格式,再将byte数据格式的所述key值和所述value值拼接为第四byte数据。

本步骤的目的是:提供一种将隶属于map数据的接口参数转换为byte数据的方案。

具体的,当接口参数有多个时,首先一一将各接口参数转化为byte数据,然后再通过拼接,获得所有接口参数共同对应的byte数据。

步骤103,根据所述byte数据,构建一维数组。

本步骤的目的是:将byte数据写入一维数组jbyteArray,方便之后java层的调用。

步骤104,调用NewDirectByteBuffer函数,将所述一维数组存储在C++存储内存中。

本步骤的目的是:为一维数组jbyteArray分配连续的存储内存空间,以实现数据的高效传输。

具体执行代码为:

NewDirectByteBuffer(buffer->data(),bufferlen)。

其中,data()为获取数据的函数,用来获取一维数组jbyteArray;buffer为NewDirectByteBuffer函数为一维数组jbyteArray分配的存储内存;bufferlen为该存储内存的长度(大小)。

步骤105,创建env变量,并将所述env变量存储在所述第一线程的线程局部存储变量中。

本步骤的目的是:之后的数据传输必须用到该env变量,必须提前创建。

具体的,env变量作为系统的JNIEnv变量,是jni调用接口的环境变量。由于调用NewDirectByteBuffer函数需要使用到env变量,而该变量不支持跨线程访问,所以调用NewDirectByteBuffer函数则必须是在此调用者的线程所属的env变量,否则会导致程序出错。

本步骤将env变量存储在所述第一线程的线程局部存储变量中,在调用该env变量的时候都从线程局部存储变量中获取,这样的话任意地方需要用到env变量时,通过调用接口获取的env变量都是自身线程的env变量,从而不会导致程序出错。

步骤106,将所述env变量赋值为所述C++存储内存的值。

本步骤的目的是:将C++存储内存中存储的数据转入到env变量中,方便之后java层的调用。

具体执行代码为:

env->NewDirectByteBuffer(buffer->data(),bufferlen)。

步骤107,将所述C++存储内存转换为java存储内存。

本步骤的目的是:通过内存转换,实现SO层向java层的数据传输。

步骤108,根据所述java存储内存,获取所述一维数组。

本步骤的目的是:通过读取java存储内存,使java层获取一维数组jbyteArray。

步骤109,根据所述一维数组,获取所述SO层API接口的接口参数中的性能统计数据。

本步骤的目的是:从一维数组jbyteArray中分离出与性能统计相关的数据,方便接下来进行性能统计。

具体的,性能统计数据可以是被调用函数的名称、传输的数据大小、被调用函数在调用时消耗的时间和线程id等数据。

本步骤设计了一个data结构来存储性能统计数据,本实施例每次在调用SO层API接口时都会创建一个data结构,并将其存储到一个全局的list链表中,然后将相关的性能统计数据存储该data结构。

具体执行代码为:

Struct data{

String funcname;

size_t len_;

Uint64_t time;

Uint64_t threaid;

}。

其中,String funcname为被调用函数的名称,size_t len_为传输的数据大小,Uint64_t time为被调用函数在调用时消耗的时间,Uint64_t threaid为线程id。

步骤110,根据所述性能统计数据,调用统计线程,进行所述SO层API接口的性能统计。

本步骤的目的是:通过专门用来进行性能统计的统计线程,进行SO层API接口的性能统计。

具体的,SO层API接口的接口参数是在C++层调用时产生的,为了保证统计数据的准确性,用于性能统计的线程只能有一个。当统计线程发生调用时,可以在C++层得到调用的时机,因此可以预先设置一个关键的阈值来,通过判断当前的调用是否超过了该阈值来决定是否允许被调用。若超过阈值,则可以获取相关API接口名称并进行打印,从而可以告知开发者在那里存在超过阈值的调用,从而可以进行检测,同时还可以在c++层获取函数调用的堆栈信息,从而可以将整个调用链路打印出来,从而更便捷的告知开发者是从那个函数入口调用过来的,从而更好查找问题和优化问题。

在一种可能的实施例中,本发明还给出了一种较优的创建存储env变量的方案,具体方案为:

所述创建env变量,并将所述env变量存储在所述第一线程的线程局部存储变量中,包括步骤31至步骤34。

步骤31,调用虚拟机接口,创建所述env变量。

本步骤的目的是:

具体执行代码为:创建出空白的env变量,方便调用函数时的使用。

g_jvm->GetEnv(&env,JNI_VERSION_1_6)。

具体的,本步骤创建的env变量为空变量,可以通过赋值的方式,为其添加具体的值。

步骤32,创建第一变量和第一变量释放监测函数。

本步骤的目的是:本步骤中的第一变量和第一变量释放监测函数是后续第一线程的所述线程局部存储变量中的必要元素。

具体执行代码为:

static pthread_key_t gjni

static void JDestructor(void*gjni)。

其中,第一变量gjni需要定义为不会被释放的全局变量,否则在其释放后,后续再次访问该变量时会导致程序出错。

而在创建完第一变量gjni后,需要编写一个第一变量释放监测函数,通过该第一变量释放监测函数知道第一变量gjni是否被释放,从而方便后续功能确定能否继续访问env变量。Destructor函数提供第一变量释放的时机点,从而方便判断是否能继续执行其他功能。

步骤33,根据所述第一变量和所述第一变量释放检测函数,调用pthread_key_create函数,创建所述第一线程的所述线程局部存储变量。

本步骤的目的是:调用pthread_key_create函数,创建第一线程的所述线程局部存储变量,用以存储env变量。

具体执行代码为:

pthread_key_create(&gjni,&JDestructor)。

步骤34,将所述env变量存储在所述线程局部存储变量中。

本步骤的目的是:将env变量存储在线程局部存储变量中,方便之后进行数据的传输。

具体执行代码为:

pthread_setspecific(gjni,env)。

在某一线程调用C++存储内存的控制权在对C++存储内存进行控制时,若其他调用者也调用C++存储内存的控制权,将会导致程序出错,为了防止这种情况的发生,本发明还提供了一种较优的控制方案,具体方案为:

所述将所述C++存储内存转换为java存储内存,包括步骤41至步骤45。

步骤41,创建一维数组封装类。

本步骤的目的是:方便之后对C++存储内存及其长度,以及C++存储内存的控制权的封装。

步骤42,将所述C++存储内存及其长度存储进所述一维数组封装类中。

本步骤的目的是:避免之后多线程对其控制导致的程序出错。

步骤43,将所述C++存储内存的控制权转入到所述一维数组封装类中。

本步骤的目的是:避免多线程调用C++存储内存的控制权导致的程序出错。

步骤44,利用move操作,调用所述C++存储内存的控制权,将所述C++存储内存赋值给成员变量。

本步骤的目的是:避免多线程调用C++存储内存的控制权导致的程序出错。

步骤41至步骤44的具体执行代码为:

Class jbyteArrayIO{

jbyteArrayIO(unique_ptrbuffer,size_t len):buffer_(move(buffer),len_(len)。

其中,Move函数可以将控制权从一个变量转移到另一个变量。

这里将c++层的buffer和长度传入这个类进行保存,并且调用者需要将buff的控制权转入到jbyteArrayIO中。为了便于对buffer的管理也防止调用者人为犯错,通过使用unique_ptr智能指针来对buff进行管理,而由于unique_ptr是不能进行拷贝的在调用者调用时,要求其将buffer的控制权转移进来才能够正确调用,也必须使用move操作来将参数的buffer赋值给成员变量buffer_。

步骤45,根据所述成员变量,调用所述NewDirectByteBuffer函数,将所述C++存储内存转换为所述java存储内存。

本步骤的目的是:进行内存转换,方便java层的线程获取接口参数。

具体执行代码为:

javabuffer_=env->NewDirectByteBuffer(buffer_,len_));}。

由于本发明中涉及到了较多的变量和java对象,这些变量和java对象的生命周期必须相一致,否则会出现程序出错。为此,本发明还专门提供了一个用来进行生命周期管理的方案,避免程序因生命周期不一致而出现错误情况的发生,具体方案为:

所述将所述C++存储内存转换为java存储内存之后,所述方法还包括步骤51至步骤57。

步骤51,创建生命周期控制模板类。

本步骤的目的是:用于构建生命周期控制构造函数的必要步骤。

具体执行代码为:

class ScopedLocal{。

步骤52,将访问jni接口的参数作为第一成员变量。

本步骤的目的是:用于构建生命周期控制构造函数的必要步骤。

具体的,本步骤将访问jni接口的参数存储到生命周期控制模板类classScopedLocal中,只需要在首次调用jni接口时获取一次后将其存储下来,后续通过读取便可直接使用,省去了每次获取的时间,提高整体效率。

具体执行代码为:

JNIEnv*env_。

步骤53,创建jobject类型的第二成员变量。

本步骤的目的是:用于构建生命周期控制构造函数的必要步骤。

具体的,选用jobject的目的是,其可以转化成java的其他类型的对象,其是一种java对象的泛指,其既可以转jint也可以转其他对象。

具体执行代码为:

jobject obj_。

步骤54,创建string类型的函数名变量。

本步骤的目的是:函数名变量是包含类和函数的拼接,防止2个不同的类有相同的函数名,加上类则可以保障每个函数名称的唯一性。

具体执行代码为:

String name_。

步骤55,根据所述第一成员变量、所述第二成员变量和所述函数名变量,将所述生命周期控制模板类实例化,获得生命周期控制构造函数。

本步骤的目的是:该生命周期控制构造函数用以控制变量和java对象的生命周期。

具体执行代码为:

ScopedLocal(JNIEnv*env_,jobject obj_,String name_){。

步骤56,将所述第一成员变量赋值为所述env变量。

本步骤的目的是:用于构建生命周期控制构造函数的必要步骤。

具体执行代码为:

env_=env。

步骤57,将所述第二成员变量赋值为所述一维数组封装类的对象实例。

本步骤的目的是:用于构建生命周期控制构造函数的必要步骤。

obj_=obj。

具体的,通过该构造函数,可以获取jbyteArrayIO对象的内存大小,从而可以知道其传输数据时需要的内存大小。

为了保证程序的正常运行,该构造函数还提供以下控制:

1、判断obj_是否为空;

2、若obj_不为空,则删除掉对obj_的局部引用;

3、删除掉obj_变量,从而再进行C++内存和java的内存释放操作。

具体执行代码为:

~ScopedLocal(){

if(obj_!=null);

env_->DeleteGlobalRef(obj_);

delete obj_;}。

所有的java和C++直接的调用关系,都必须使用上述步骤定义的ScopedLocal类来封装参数,这样才可以知道所有的调用的API接口的接口参数,才能够统计出所有的数据。

在实际应用中,有可能会有其他线程与第一线程同时调用SO层的API接口,这时也需要获取其他线程的调用情况,以准确统计出接口参数的调用情况。但是,统计线程只有一个,这种情况下容易出现统计拥堵的情况,不利于统计的进行,甚至会导致出现程序出错。为此,本发明还提供了以下方案,来高效地完成多线程的数据上传统计,具体方案为:

在一种可能的实施例中,所述根据所述性能统计数据,调用统计线程,进行所述SO层API接口的性能统计,包括步骤61至步骤63。

步骤61,创建传输队列。

本步骤的目的是:利用传输队列,实现不同线程的性能统计数据的有序上传,方便性能统计的快速准确进行。

具体的,本步骤创建的传输队列是第一线程独有的。

步骤62,将所述性能统计数据存储在所述传输队列中。

本步骤的目的是:将性能统计数据存储在传输队列,方便数据统计。

步骤63,利用所述上传队列,在所述统计线程空闲时,将所述性能统计数据传输至所述统计线程中,进行所述SO层API接口的性能统计。

本步骤的目的是:利用统计线程的空闲间隔,依次将不同线程的性能统计数据传输至统计线程中,方便性能统计的进行。

基于与方法同样的发明构思,本发明实施例还提供了一种性能统计装置,如图2所示为该装置实施例的结构示意图,具体包括:

接口参数获取模块701,用于获取第一线程当前调用的SO层API接口的接口参数;

数据转化模块702,用于将所述接口参数转化为byte数据;

一维数组构建模块703,用于根据所述byte数据,构建一维数组;

内存分配模块704,用于调用NewDirectByteBuffer函数,将所述一维数组存储在C++存储内存中;

env变量创建模块705,用于创建env变量,并将所述env变量存储在所述第一线程的线程局部存储变量中;

第一赋值模块706,用于将所述env变量赋值为所述C++存储内存的值;

内存转换模块707,用于将所述C++存储内存转换为java存储内存;

一维数组获取模块708,用于根据所述java存储内存,获取所述一维数组;

性能统计数据获取模块709,用于根据所述一维数组,获取所述SO层API接口的接口参数中的性能统计数据;

性能统计模块710,用于根据所述性能统计数据,调用统计线程,进行所述SO层API接口的性能统计;

所述数据转化模块702,包括:

数据类型确定模块,用于确定所述接口参数的数据类型;

第一转化模块,用于在所述接口参数的数据类型为int数据时,将所述接口参数转化为由4个字节组成的第一byte数据;

第二转化模块,用于在所述接口参数的数据类型为string数据时,将所述接口参数转化为第二byte数据;

第三转化模块,用于在所述接口参数的数据类型为list数据时,先将所述接口参数转化为若干个string数据,再将所述若干个string数据转化为第三byte数据;

第四转化模块,用于在所述接口参数的数据类型为map数据时,先将所述接口参数的key值和value值分别转化为byte数据格式,再将byte数据格式的所述key值和所述value值拼接为第四byte数据。

在一种可能的实施例中,所述env变量创建模块705,包括:

第一创建模块,用于调用虚拟机接口,创建所述env变量;

第二创建模块,用于创建第一变量和第一变量释放监测函数;

第三创建模块,用于根据所述第一变量和所述第一变量释放检测函数,调用pthread_key_create函数,创建所述第一线程的所述线程局部存储变量;

env变量存储模块,用于将所述env变量存储在所述线程局部存储变量中。

在一种可能的实施例中,所述内存转换模块704,包括:

一维数组封装类创建模块,用于创建一维数组封装类;

第一存储模块,用于将所述C++存储内存及其长度存储进所述一维数组封装类中;

控制权转入模块,用于将所述C++存储内存的控制权转入到所述一维数组封装类中;

第二赋值模块,用于利用move操作,调用所述C++存储内存的控制权,将所述C++存储内存赋值给成员变量;

转换模块,用于根据所述成员变量,调用所述NewDirectByteBuffer函数,将所述C++存储内存转换为所述java存储内存。

在一种可能的实施例中,所述装置还包括:

生命周期控制模板类创建模块,用于创建生命周期控制模板类;

第四创建模块,用于将访问jni接口的参数作为第一成员变量;

第五创建模块,用于创建jobject类型的第二成员变量;

第六创建模块,用于创建string类型的函数名变量;

构造函数获取模块,用于根据所述第一成员变量、所述第二成员变量和所述函数名变量,将所述生命周期控制模板类实例化,获得生命周期控制构造函数;

第三赋值模块,用于将所述第一成员变量赋值为所述env变量;

第四赋值模块,用于将所述第二成员变量赋值为所述一维数组封装类的对象实例。

在一种可能的实施例中,所述性能统计模块709,包括:

第七创建模块,用于创建传输队列;

统计数据存储模块,用于将所述性能统计数据存储在所述传输队列中;

统计模块,用于利用所述上传队列,在所述统计线程空闲时,将所述性能统计数据传输至所述统计线程中,进行所述SO层API接口的性能统计。

基于与方法同样的发明构思,本发明实施例还提供了一种计算机设备,包括:

存储器,用于存储计算机程序;

处理器,用于执行该计算机程序以实现如上述方法实施例中所述的性能统计方法的步骤。

基于与方法同样的发明构思,本发明实施例还提供一种计算机可读存储介质,其上存储有计算机程序,该计算机程序被处理器执行时以实现如上述方法实施例中所述的性能统计方法的步骤。

本发明实施例与现有技术相比,具有如下的优点和有益效果:

本发明实施例先将获取到的API接口参数转化为byte数据,并构建一维数组,之后为该一维数组分配了连续的内存空间,从而在SO层向java层传输时,利用NewDirectByteBuffer函数,通过整块内存空间进行数据传输,提高了数据的传输效率,从而能够准确高效地对SO层API接口进行性能统计。

本领域内的技术人员应明白,本申请的实施例可提供为方法、系统、或计算机程序产品。因此,本申请可采用完全硬件实施例、完全软件实施例、或结合软件和硬件方面的实施例的形式。而且,本申请可采用在一个或多个其中包含有计算机可用程序代码的计算机可用存储介质(包括但不限于磁盘存储器、CD-ROM、光学存储器等)上实施的计算机程序产品的形式。

本申请是参照根据本申请实施例的方法、装置(装置、系统)、和计算机程序产品的流程图和/或方框图来描述。应理解可由计算机程序指令实现流程图和/或方框图中的每一流程和/或方框、以及流程图和/或方框图中的流程和/或方框的结合。可提供这些计算机程序指令到通用计算机、专用计算机、嵌入式计算机或者其他可编程数据处理设备的处理器以产生一个机器,使得通过计算机或其他可编程数据处理设备的处理器执行的指令产生用于实现在流程图一个流程或多个流程和/或方框图一个方框或多个方框中指定的功能的装置。

这些计算机程序指令也可存储在能引导计算机或其他可编程数据处理设备以特定方式工作的计算机可读存储器中,使得存储在该计算机可读存储器中的指令产生包括指令装置的制造品,该指令装置实现在流程图一个流程或多个流程和/或方框图一个方框或多个方框中指定的功能。

这些计算机程序指令也可装载到计算机或其他可编程数据处理设备上,使得在计算机或其他可编程设备上执行一系列操作步骤以产生计算机实现的处理,从而在计算机或其他可编程设备上执行的指令提供用于实现在流程图一个流程或多个流程和/或方框图一个方框或多个方框中指定的功能的步骤。

尽管已描述了本申请的优选实施例,但本领域内的技术人员一旦得知了基本创造概念,则可对这些实施例作出另外的变更和修改。所以,所附权利要求意欲解释为包括优选实施例以及落入本申请范围的所有变更和修改。

显然,本领域的技术人员可以对本申请进行各种改动和变型而不脱离本申请的精神和范围。这样,倘若本申请的这些修改和变型属于本申请权利要求及其等同技术的范围之内,则本申请也意图包括这些改动和变型在内。

技术分类

06120113822700