1.一种基于模式的Python代码内存泄漏检测方法,其特征在于,包括以下步骤:S1、输入项目的源代码,遍历项目中的所有代码文件,加载每一个Python代码文件 利用Python标准库中的ast模块得到每一个Python代码文件 对应的抽象语法树S2、利用抽象解释器技术基于步骤S1获得的抽象语法树 进行类型推断,得到类型树其中类型树 中的节点表示抽象类型,节点之间的关系表示从属关系;
S3、遍历步骤S2获得的类型树 中的每个实例类型i,获取每个实例类型i在类型树中的所有子节点,然后使用预定义的内存泄漏模式检查每个子节点b是否存在内存泄漏,如果满足其中一个内存泄漏模式,则记录引起内存泄漏的循环引用,每一个循环引用记录为一个节点序列[v0,v1,...vn],其中节点序列中的每个节点vi为类型树中的节点,相邻的节点之间存在引用关系,并且满足v0=vn;
步骤S2中通过类型推断得到类型树的具体步骤如下:S21、根据Python定义的类型,封装若干个抽象类型;
S22、对于每个Python代码文件 对应的抽象语法树 使用抽象解释器进行类型推断得到类型树 类型树 中的每个节点表示一种抽象类型且抽象语法树 对应的模块类型加入到类型树T中作为根节点,节点之间的关系表示从属关系即子节点的定义在父节点内;
S23、依次遍历类型树 中的每个函数类型的节点,得到所有函数类型;针对每一个函数类型,判断该函数类型是否在类型推断中存在调用,即有没有至少一个调用类型所调用的函数类型是该函数类型;如果有,则跳过继续对下一个函数类型进行判断,如果没有,则将其视为新产生的函数类型并创建一个调用类型,以未知类型作为传入参数,使用抽象解释器调用一次新创建的调用类型。
2.根据权利要求1所述的一种基于模式的Python代码内存泄漏检测方法,其特征在于,步骤S21中封装的抽象类型包括以下11种:
1)模块类型:mod
2)函数类型:fun
3)调用类型:invoke
4)类类型:cls
5)实例类型:ins
6)方法类型:meth
7)组合类型:任意类型的集合;
8)字典类型:dict<τ,τ>,其中两个τ分别表示字典中的健和值的类型;
9)列表类型:list<τ>,其中τ表示列表中的元素的类型;
10)元组类型:tuple<τ>,其中τ表示元组中的元素的类型;
11)集合类型:set<τ>,其中τ表示集合中的元素的类型。
3.根据权利要求1所述的一种基于模式的Python代码内存泄漏检测方法,其特征在于,步骤S3中使用预定义的内存泄漏模式检查每个子节点b是否存在内存泄漏的具体步骤如下:
S31、预定义模式1为自引用造成的内存泄漏,判断子节点b是否满足模式1,如果b与i相同,则认为满足模式1,此时记录引起内存泄漏的循环引用为[i];
S32、预定义模式2为一个实例与容器之间的循环引用造成的内存泄漏,判断子节点b是否满足模式2,如果b严格包含i,则认为满足模式2,此时记录引起内存泄漏的循环引用为[b,i];
S33、预定义模式3为一个实例与方法之间的循环引用造成的内存泄漏,判断是否满足模式3,判断步骤如S331和S332:S331、如果子节点b属于方法类型,则检查b所属的实例类型b.ins,如果b.ins与i相同,则认为满足模式3,此时记录引起内存泄漏的循环引用为[b.ins,i];
S332、如果子节点b属于组合类型,则检查b中包含的每个类型t,如果存在一个方法类型的t,其所属的实例类型t.ins与i相同,则认为满足模式3,此时记录引起内存泄漏的循环引用为[t.ins,i];
S34、预定义模式4为两个实例之间的循环引用造成的内存泄漏,判断子节点b是否满足模式4,判断步骤如S341和S342:S341、如果子节点b属于实例类型,并且b与i不相同,则检查b的每个子节点,如果存在一个子节点c是实例类型并且与i等价,则认为满足模式4,此时记录引起内存泄漏的循环引用为[c,i];
S342、如果子节点b属于组合类型,则检查b中包含的每个类型t,如果存在一个t属于实例类型,则进一步检查t内的每个子节点c,如果存在一个子节点c是实例类型并且与i等价,则认为满足模式4,此时记录引起内存泄漏的循环引用为[c,i];
S35、预定义模式5为两个实例与容器之间的循环引用造成的内存泄漏,判断子节点b是否满足模式5,判断步骤如S351和S352:S351、如果子节点b属于实例类型,并且b与i不相同,则进一步检查b内的每个子节点,如果存在一个子节点c是实例类型并且包含i,则认为满足模式5,此时记录引起内存泄漏的循环引用为[c,i];
S352、如果子节点b属于组合类型,则检查b中包含的每个类型t,如果存在一个t属于实例类型,则进一步检查t内的每个子节点c,如果存在一个子节点c是实例类型并且包含i,则认为满足模式5,此时记录引起内存泄漏的循环引用为[c,i];
S36.预定义模式6为两个实例与方法之间的循环引用造成的内存泄漏,判断子节点b是否满足模式6,判断步骤如下:
如果子节点b属于实例类型,则进一步检查b的每个子节点c,如果存在一个子节点c是方法类型并且其所属的实例类型c.ins与i相同,则认为满足模式6,此时记录引起内存泄漏的循环引用为[c.ins,i]。
4.根据权利要求1所述的一种基于模式的Python代码内存泄漏检测方法,其特征在于,步骤S32中对于任意两个类型x和y,两者之间的严格包含关系判断步骤如下:
1)如果x属于字典类型,则检查x的健或值是否与y等价,如果是则认为类型x包含类型y;
2)如果x属于集合类型、列表类型或元祖类型,则检查y是否属于x中的一项,如果是则认为类型x包含类型y;
3)如果x属于组合类型,则检查x中是否存在一个类型t包含类型y,如果是则认为类型x包含类型y。
5.根据权利要求1所述的一种基于模式的Python代码内存泄漏检测方法,其特征在于,步骤S34中,对于任意两个类型x和y,两者之间的等价关系判断步骤如下:
1)如果x不属于组合类型,则判断x和y是否相同,如果相同则认为x和y等价;
2)如果x属于组合类型,则检查x中是否存在一个类型t与y等价,如果存在则认为x和y等价。
6.根据权利要求1所述的一种基于模式的Python代码内存泄漏检测方法,其特征在于,步骤S35中,对于任意两个类型x和y,两者之间的包含关系判断步骤如下:
1)如果x属于字典类型,则检查x的健或值是否与y相同,如果相同则认为类型x包含类型y;
2)如果x属于集合类型、列表类型或元祖类型,则检查y是否属于x,如果是则认为类型x包含类型y;
3)如果x属于组合类型,则检查x中是否存在一个类型t包含类型y,如果存在则认为类型x包含类型y。