一种残膜回收机防缠绕挑膜装置的制 一种秧草收获机用电力驱动行走机构

程序内存监控方法、装置、计算机设备以及存储介质与流程

2022-03-09 01:13:17 来源:中国专利 TAG:


1.本技术涉及计算机技术领域,特别是涉及一种程序内存监控方法、装置、计算机设备、存储介质和计算机程序产品。


背景技术:

2.随着程序开发技术的发展,各种程序开发工具也得到不断的更新演进,如对于游戏开发技术,游戏引擎这种开发工具在游戏开发中占据着越来越大的作用。游戏引擎是指一些已编写好的可编辑电脑游戏系统或者一些交互式实时图像应用程序的核心组件。这些系统为游戏设计者提供各种编写游戏所需的各种工具,其目的在于让游戏设计者能容易和快速地做出游戏程式而不用由零开始。游戏引擎包含以下系统:渲染引擎(即“渲染器”,含二维图像引擎和三维图像引擎)、物理引擎、碰撞检测系统、音效、脚本引擎、电脑动画、人工智能、网络引擎以及场景管理。而基于游戏引擎开发的游戏项目可能面临逻辑内存过高的问题,此时可以通过内存监控来确定游戏的内存占用情况,从而进行内存的分析与优化。
3.目前,一般可以通过在程序开发时一般可以通过内存抓取工具来截取程序内的内存占用情况,如对于游戏程序的开发,可以通过游戏引擎自带的内存抓取工具以快照的方式截取当前内存中的活跃对象,向用户提供瞬时的活跃对象快照列表,从而实现游戏内存的监控,然而这种监控方式只能提供内存中的存活对象列表,用户无法获知对象的创建来源信息,内存监控的效果较差。


技术实现要素:

4.基于此,有必要针对上述技术问题,提供一种能够提高程序内存监控效果的程序内存监控方法、装置、计算机设备、计算机可读存储介质和计算机程序产品。
5.第一方面,本技术提供了一种程序内存监控方法。所述方法包括:
6.确定程序对应程序脚本后端对象,读取所述程序脚本后端对象对应的创建信息与函数调用堆栈数据;
7.基于所述创建信息,确定所述程序脚本后端对象的托管堆内存信息;
8.获取所述程序对应程序脚本后端对象的销毁信息;
9.根据所述托管堆内存信息、所述销毁信息以及所述函数调用堆栈数据,获取所述程序对应的内存监控结果。
10.第二方面,本技术还提供了一种程序内存监控装置。所述装置包括:
11.创建信息获取模块,用于确定程序对应程序脚本后端对象,读取所述程序脚本后端对象对应的创建信息与函数调用堆栈数据;
12.托管堆信息获取模块,用于基于所述创建信息,确定所述程序脚本后端对象的托管堆内存信息;
13.销毁信息获取模块,用于获取所述程序对应程序脚本后端对象的销毁信息;
14.监控结果获取模块,用于根据所述托管堆内存信息、所述销毁信息以及所述函数
调用堆栈数据,获取所述程序对应的内存监控结果。
15.第三方面,本技术还提供了一种计算机设备。所述计算机设备包括存储器和处理器,所述存储器存储有计算机程序,所述处理器执行所述计算机程序时实现以下步骤:
16.确定程序对应程序脚本后端对象,读取所述程序脚本后端对象对应的创建信息与函数调用堆栈数据;
17.基于所述创建信息,确定所述程序脚本后端对象的托管堆内存信息;
18.获取所述程序对应程序脚本后端对象的销毁信息;
19.根据所述托管堆内存信息、所述销毁信息以及所述函数调用堆栈数据,获取所述程序对应的内存监控结果。
20.第四方面,本技术还提供了一种计算机可读存储介质。所述计算机可读存储介质,其上存储有计算机程序,所述计算机程序被处理器执行时实现以下步骤:
21.确定程序对应程序脚本后端对象,读取所述程序脚本后端对象对应的创建信息与函数调用堆栈数据;
22.基于所述创建信息,确定所述程序脚本后端对象的托管堆内存信息;
23.获取所述程序对应程序脚本后端对象的销毁信息;
24.根据所述托管堆内存信息、所述销毁信息以及所述函数调用堆栈数据,获取所述程序对应的内存监控结果。
25.第五方面,本技术还提供了一种计算机程序产品。所述计算机程序产品,包括计算机程序,该计算机程序被处理器执行时实现以下步骤:
26.确定程序对应程序脚本后端对象,读取所述程序脚本后端对象对应的创建信息与函数调用堆栈数据;
27.基于所述创建信息,确定所述程序脚本后端对象的托管堆内存信息;
28.获取所述程序对应程序脚本后端对象的销毁信息;
29.根据所述托管堆内存信息、所述销毁信息以及所述函数调用堆栈数据,获取所述程序对应的内存监控结果。
30.上述程序内存监控方法、装置、计算机设备、存储介质和计算机程序产品,其中方法通过确定程序对应程序脚本后端对象,读取程序脚本后端对象对应的创建信息与函数调用堆栈数据;基于创建信息,确定程序脚本后端对象的托管堆内存信息;获取程序对应程序脚本后端对象的销毁信息;根据托管堆内存信息、销毁信息以及函数调用堆栈数据,获取程序对应的内存监控结果。本技术通过确定程序脚本后端对象从创建过程和销毁过程的信息,基于创建过程中的函数调用堆栈数据以及销毁过程中的销毁信息,可以有效地对程序运行过程中,程序脚本内存对象的创建来源以及销毁情况进行确定,基于创建过程中的托管堆内存信息,可以有效对程序内存变化的情况进行确定,从而可以有效提高内存监控的监控效果。
附图说明
31.图1为一个实施例中程序内存监控方法的流程示意图;
32.图2为一个实施例中确定托管堆内存信息步骤的流程示意图;
33.图3为一个实施例中获取程序脚本后端对象的销毁信息步骤的流程示意图;
34.图4为另一个实施例中获取程序脚本后端对象的销毁信息步骤的流程示意图;
35.图5为一个实施例中记录到磁盘中的数据结构示意图;
36.图6为一个实施例中获取程序对应程序脚本后端对象的函数调用堆栈数据步骤的流程示意图;
37.图7为一个实施例中堆栈回溯步骤的示意图;
38.图8为一个实施例中函数调用堆栈的压缩过程的示意图;
39.图9为一个实施例中对象创建过程以及监控记录过程的流程示意图;
40.图10为一个实施例中调用地址信息还原过程的流程示意图;
41.图11为一个实施例中生成可视化报告页面数据的流程示意图;
42.图12为一个实施例中内存监控结果的展示过程的流程示意图;
43.图13为一个实施例中程序内存监控方法在移动终端实现过程的流程示意图;
44.图14为一个实施例中对内存监控结果进行可视化展示的示意图;
45.图15为一个实施例中程序内存监控装置的结构框图;
46.图16为一个实施例中计算机设备的内部结构图。
具体实施方式
47.为了使本技术的目的、技术方案及优点更加清楚明白,以下结合附图及实施例,对本技术进行进一步详细说明。应当理解,此处描述的具体实施例仅仅用以解释本技术,并不用于限定本技术。
48.如图1所示,提供了一种程序内存监控方法,本实施例以该方法应用于终端进行举例说明,可以理解的是,该方法也可以应用于服务器,还可以应用于包括终端和服务器的系统,并通过终端和服务器的交互实现。本实施例中,该方法包括以下步骤:
49.步骤102,确定程序对应程序脚本后端对象,读取程序脚本后端对象对应的创建信息与函数调用堆栈数据。
50.其中,程序是本技术的程序内存监控方法的监控对象,在具体的实施例中本技术的程序具体可以包括移动终端或者主机端等终端上的客户端游戏,这些游戏一般基于游戏引擎开发。在游戏运行过程中,游戏占用的逻辑内存在不断发生变化。程序脚本后端对象则具体是指程序在运行过程中所创建的对象,如对于基于unity引擎开发的游戏,其程序脚本后端对象可以为il2cpp对象。il2cpp是一种由unity开发的脚本后端,可在为各种平台构建项目时替代mono。使用il2cpp构建项目时,unity引擎会在为所选平台创建本机二进制文件(如apk)之前将脚本和程序集内的il代码转换为c 。在游戏运行过程中,基于il2cpp脚本后端所创建的对象即为il2cpp对象,也就是本技术方案中的程序脚本后端对象。创建信息则具体是指程序脚本后端对象对应的类型、大小以及地址等信息。函数调用堆栈数据则是用于记录程序脚本后端对象在创建过程中的函数调用信息。
51.具体地,可以通过本技术的程序内存监控方法,来监控终端上程序运行过程中的逻辑内存(虚拟内存)变化。当终端系统上的程序启动后,即可通过本技术的程序内存监控方法来实施监控,在程序运行的过程中,程序的原始代码会被程序脚本后端转化为可在终端上运行的代码,并在终端的逻辑内存内创建相应的程序脚本后端对象。而终端则可基于本技术的程序内存监控方法,在程序启动之后的运行过程中,记录下程序对应程序脚本后
端对象的创建信息与函数调用堆栈数据。其中记录下程序对应程序脚本后端对象的创建信息可以将其分解为各个基础类型对象的建立,如对于il2cpp对象,记录il2cpp对象创建的关键技术点是找到能够覆盖所有il2cpp对象创建的逻辑点。通过分析il2cpp虚拟机,可知所有il2cpp对象的创建都会被收敛归纳为三种基础类型的创建,它们分别是object、array、string这三种类型,因此可以通过记录三种类型的基础对象,来实现对于程序脚本后端对象创建信息的记录。而函数调用堆栈数据,则可以用于高效定位对象的创建来源,函数调用堆栈数据具体可以通过堆栈回溯机制来获取。
52.步骤104,基于创建信息,确定程序脚本后端对象的托管堆内存信息。
53.其中,托管堆是指内存托管堆,其可以在真正使用内存之前,预先申请分配一定数量的内存块留作备用。当有新的内存需求时,从内存池中分出一部分内存块使用,若内存块不够再继续申请新的内存。
54.具体地,在程序运行过程中,程序对应的托管堆会因为程序脚本后端对象的创建而产生变化。因此可以在每次程序脚本后端对象创建后,记录下本次创建过程中分配对象的大小、类型、地址、函数调用堆栈,同时会调用获取此时托管堆的大小,并一并记录下来,得到程序脚本后端对象的托管堆内存信息。通过记录下各个程序脚本后端对象的创建过程中托管堆的变化,可以有效地对程序内存变化情况进行监控。
55.步骤106,获取程序对应程序脚本后端对象的销毁信息。
56.其中,销毁信息是指在程序运行过程中被销毁的程序脚本后端对象的信息,具体包括了程序脚本后端对象的对象地址。当程序脚本后端对象在程序运行过程中的业务处理逻辑未被引用到时,可以执行销毁操作将其销毁。同时在程序脚本后端对象的销毁过程中,可以记录下即将被销毁的程序脚本后端对象的对象地址,供后续工具链还原内存使用情况时使用。
57.具体地,在程序运行过程中,不仅包含了程序脚本后端对象的创建过程,还包括了对应对象的销毁过程。在每次的程序脚本后端对象中,终端都可以基于本技术的程序内存监控方法记录下对应的销毁信息,并进一步地确定在程序脚本后端对象销毁过程中的内存使用变化情况。
58.步骤108,根据托管堆内存信息、销毁信息以及函数调用堆栈数据,获取程序对应的内存监控结果。
59.其中,内存监控结果具体可以是程序运行过程中内存变化的可视化展示,包括了托管堆的内存变化展示以及函数调用堆栈地址的展示。
60.具体地,终端在从程序运行的过程中得到托管堆内存信息、销毁信息以及函数调用堆栈数据之后,可以基于所有的托管堆内存信息、销毁信息以及函数调用堆栈数据来生成程序运行过程中的内存监控结果,从程序开始运行到运行结束之间,每一个程序脚本后端对象在创建时都有一个托管堆内存信息以及函数调用堆栈数据与之对应,每一个程序脚本后端对象在销毁时都有一个销毁信息与之对应。通过记录托管堆内存信息、销毁信息以及函数调用堆栈数据的时间节点,可以有效对程序内存变化的原因进行分析,从而生成可视化的内存监控结果,并向用户展示。在其中一个实施例中,具体可以通过利用python生成网页,以网页的形式来展示程序运行过程中的内存变化。
61.上述程序内存监控方法,通过确定程序对应程序脚本后端对象,读取程序脚本后
端对象对应的创建信息与函数调用堆栈数据;基于创建信息,确定程序脚本后端对象的托管堆内存信息;获取程序对应程序脚本后端对象的销毁信息;根据托管堆内存信息、销毁信息以及函数调用堆栈数据,获取程序对应的内存监控结果。本技术通过确定程序脚本后端对象从创建过程和销毁过程的信息,基于创建过程中的函数调用堆栈数据以及销毁过程中的销毁信息,可以有效地对程序运行过程中,程序脚本内存对象的创建来源以及销毁情况进行确定,基于创建过程中的托管堆内存信息,可以有效对程序内存变化的情况进行确定,从而可以有效提高内存监控的监控效果。本技术的方案可以高效得掌握程序运行时,托管堆内存使用情况,大幅提升托管堆内存分析效率,托管堆内存优化效率。在其中一个实施例中,还可以集成本技术的程序内存监控方法至对游戏进行性能测试的自动化流水线,从而实现针对游戏托管堆内存占用的持续监控和自动化报告,防患于未然,大幅降低了由于托管堆内存增涨所引发的性能风险。
62.在其中一个实施例中,如图2所示,步骤104包括:
63.步骤201,获取创建信息中的对象大小信息、对象类型信息以及对象地址信息。
64.步骤203,调用预设托管堆大小获取函数,获取托管堆大小信息。
65.步骤205,根据对象大小信息、对象类型信息、对象地址信息以及托管堆大小信息,确定程序脚本后端对象的托管堆内存信息。
66.其中,对象大小信息、对象类型信息以及对象地址信息分别用于描述程序脚本后端对象的占用内存大小、对象的类型以及对象的地址。预设托管堆大小获取函数则是专门用于获取当前时刻托管堆所占用内存大小的函数。当程序运行时,如果需要创建新的程序脚本后端对象,那么在创建时可能会产生新的内存需求,此时可以从内存托管堆的内存池中分出一部分内存块使用,若内存块不够再继续申请新的内存,此时程序对应的托管堆的内存大小会发生变化。那次,在创建新的程序脚本后端对象时,可以调用预设托管堆大小获取函数,从而获取当前时刻的托管堆大小信息。
67.具体地,在程序脚本后端对象创建时,除了记录程序脚本后端对象的创建信息外,本技术基于创建信息确定程序脚本后端对象的托管堆内存信息,从而完整地录制每一个il2cpp对象的创建过程,得到最完整的内存分配信息。在其中一个实施例中,本技术的程序具体为游戏程序,该游戏程序基于unity引擎开发,此时程序脚本后端对象具体为il2cpp对象,而通过分析il2cpp虚拟机,可知所有il2cpp对象的创建都会被收敛归纳为三种基础类型的创建,它们分别是object、array、string这三种类型,因此可以分别记录下object、array、string三个类型下对象的大小与地址,得到创建信息中的对象大小信息、对象类型信息以及对象地址信息。同时可以通过预设托管堆大小获取函数scripting_gc_get_heap_size获取此时托管堆的大小。然后基于对象大小信息、对象类型信息、对象地址信息以及托管堆大小信息,确定当前时刻下托管堆内存分配的变化以及托管堆大小的变化,得到托管堆内存信息。本实施例中,通过确定程序运行过程中所创建程序脚本后端对象大小、类型以及地址,同时识别到程序脚本后端对象创建时内存托管堆的大小变化,可以有效实现对程序脚本后端对象创建过程中的内存变化进行监控,保证监控效果。
68.在其中一个实施例中,如图3所示,步骤106包括:
69.步骤302,通过预设垃圾回收算法遍历托管堆内所有的程序脚本后端对象,确定未被程序业务逻辑引用的程序脚本后端对象。
70.步骤304,通过预设回调函数记录未被程序业务逻辑引用的程序脚本后端对象的对象地址,获取程序脚本后端对象的销毁信息。
71.步骤306,对未被程序业务逻辑引用的程序脚本后端对象执行销毁操作。
72.其中,预设垃圾回收算法是指在程序运行中进行内存管理的一种算法,其可以在程序占用内存达到预设阈值时自动启动,或者由开发人员通过指令手动启动。预设垃圾回收算法可以识别出没有被程序业务逻辑引用的程序脚本后端对象,然后进行销毁。而回调函数则一个被作为参数传递的函数。本实施例中,主要通过回调函数来记录即将被销毁的程序脚本后端对象的地址,以供后续还原内存使用情况时使用。
73.具体地,在程序运行的过程中,可以通过垃圾回收算法来遍历所有存活的程序脚本后端对象,并找出没有被业务逻辑引用的程序脚本后端对象,然后进行执行销毁操作。同时,销毁逻辑真正执行前,会执行一个回调函数,通过该回调函数来记录即将被销毁的程序脚本后端对象的对象地址,供后续还原内存使用情况时使用。记录完成后,正常执行对象的销毁流程。在其中一个实施例中,程序脚本后端对象具体为il2cpp对象,此时对象销毁的流程可以参照图4所示,首先,通过启动垃圾回收算法,遍历所有存活对象,而后搜索出未被业务逻辑所引用的对象,准备执行回收,同时在回收执行前执行回调,记录被回收对象的地址后,再进行回收,释放内存。记录到磁盘中的数据结构则可以参照图5所示,如图5所示,a、b以及c三个对象依次被创建,同时创建过程中,其对应的对象大小信息、对象地址信息、函数调用栈以及托管堆大小都被分别记录,而后在销毁过程中,c、b以及a三个对象被依次销毁,并被记录下对象地址。本实施中,通过垃圾回收算法以及回调函数,来执行程序脚本后端对象的销毁操作以及被销毁程序脚本后端对象的对象地址,实现对象销毁过程的内存监控。
74.在其中一个实施例中,如图6所示,步骤102中的获取程序对应程序脚本后端对象的函数调用堆栈数据包括:
75.步骤601,通过堆栈回溯机制获取函数调用堆栈对应的调用地址信息。
76.步骤603,通过信息索引法对调用地址信息进行压缩,获取程序对应程序脚本后端对象的函数调用堆栈数据。
77.其中,堆栈回溯机制是指frame pointer机制,它是一种快速的fast unwind堆栈回溯机制,它的原理是在编译器生成汇编时,将调用者的地址记录到fp寄存器中,这样堆栈回溯过程就变成了很高效的寄存器值链式读取操作。堆栈回溯的示意图具体可以参照图7,通过fp寄存器(caller fp)可以有效地实现堆栈回溯。而信息索引法则是指一种函数调用堆栈的压缩方法,信息索引法会尝试在列表中查找是否有同样的堆栈字符串,如果找到会直接返回该堆栈字符串在列表中的索引值;如果没找到的话,工具会将该堆栈字符串存入这个列表,然后返回该堆栈字符串在列表中的索引值。采用这种压缩方式,64位系统中一个长度为8的二进制函数地址字符串,可以被压缩为长度为1的索引数值。并且录制过程中如果n次出现的相同二进制函数地址,会只存储一次,用相同的索引来记录,函数调用堆栈的压缩过程具体可以参照图8所示。所获得的函数调用堆栈数据具体可以为调用地址信息对应的索引列表。
78.具体地,本技术的方案不仅会记录下程序脚本后端对象的创建信息,也会在对象创建时记录此时的函数调用堆栈,以而帮助用户高效定位对象的创建来源。其中,函数调用堆栈信息的采集可以通过堆栈回溯机制来进行,通过在对象创建时,使用堆栈回溯机制,可
以有效地获取函数调用堆栈对应的调用地址信息,而后由于在程序项目内,如果直接存储函数调用堆栈的话,内存和磁盘占用会很大。同时申请人发现,函数调用堆栈的特征是,相同的函数地址可能会高频反复出现。根据该特征,本技术通过使用信息索引法对要记录的函数调用堆栈信息进行压缩,从而得到程序脚本后端对象的函数调用堆栈数据。在一个具体的实施例中,本技术中的程序脚本后端对象具体为il2cpp对象,此时,对象创建过程以及监控记录过程具体可以参照图9所示,首先创建il2cpp对象,在创建完成后,即可开始回溯调用堆栈。而后进行一次识别,确定回溯的地址是否超出需要记录的地址范围,当未超出时,判断继续回溯。而超出之后,则可记录回溯出来的函数调用栈,并压缩调用栈地址列表,通过信息索引法生成索引列表,并记录索引列表以及各个类型对象的对象内存地址以及内存大小。最后通过预设托管堆大小获取函数,获取托管堆大小信息,完成对象创建过程中的内存监控。本实施例中,通过堆栈回溯机制以及信息索引法,可以有效对程序脚本后端对象创建过程中的函数调用堆栈数据进行记录,从而实现更有效的内存监控。
79.在其中一个实施例中,如图10所示,步骤108包括:
80.步骤1001,将函数调用堆栈数据还原,获取二进制形式的函数调用堆栈地址列表。
81.步骤1003,通过预设符号表将二进制形式的函数调用堆栈地址列表还原为调用地址信息。
82.步骤1005,根据托管堆内存信息、销毁信息以及调用地址信息,获取程序对应的内存监控结果。
83.其中,在通过信息索引法对调用地址信息进行压缩后,需要执行对应的解压缩操作来将压缩后的调用地址信息还原,从而保证其可读性。解压的过程相当于压缩过程的逆过程,需要先将压缩后得到的索引表还原,获取二进制形式的函数调用堆栈地址列表,而后将二进制形式的函数调用堆栈地址列表还原为调用地址信息。而内存监控结果是指以可视化形式来展示程序运行过程中的内存变化,托管堆内存信息、销毁信息以及调用地址信息,可以有效地展示每一次程序脚本后端对象创建过程中的内存变化。
84.具体地,当得到程序运行过程中的托管堆内存信息、销毁信息以及函数调用堆栈数据之后,为了向外界的用户更直观地展示内存监控结果,可以先将压缩后的函数调用堆栈数据进行解压,该过程需要先将索引列表形式的函数调用堆栈数据还原,获取二进制形式的函数调用堆栈地址列表;通过预设符号表将二进制形式的函数调用堆栈地址列表还原为原始更为直观的调用地址信息。而后即可基于托管堆内存信息、销毁信息以及调用地址信息,生成向用户进行展示的内存监控结果。本实施例中,通过将函数调用堆栈数据还原为调用地址信息后,再基于托管堆内存信息、销毁信息以及调用地址信息来进行内存监控结果的展示,可以更直观地向用户展示程序运行过程中的变化,同时帮助用户高效定位对象的创建来源以及对象的销毁过程。
85.在其中一个实施例中,内存监控结果包括可视化报告页面数据,如图11所示,步骤1005包括:
86.1102,基于托管堆内存信息,生成层次结构的托管堆内存分配信息报表以及托管堆内存变化曲线图。
87.1104,根据销毁信息、调用地址信息、托管堆内存分配信息报表以及托管堆内存变化曲线图,生成可视化报告页面数据。
88.其中,托管堆内存分配信息报表以及托管堆内存变化曲线图都是直观展示程序运行过程中内存变化情况的图表数据,托管堆内存分配信息报表具体可以为hierarchy形式,而托管堆内存变化曲线图则为echarts形式。而可视化报告页面则是指通过页面将上述的销毁信息、调用地址信息、托管堆内存分配信息报表以及托管堆内存变化曲线图等信息总结归纳在一起进行展示,用户可以根据可视化报告页面,确定程序运行过程中各个时间节点的程序脚本后端对象创建过程中的托管堆内存变化。
89.具体地,在程序运行过程中,随着程序脚本后端对象的创建与销毁,托管堆内存信息在不断地发生变化,而程序内存监控的目的即为将内存信息的变化过程记录下来。因此,本技术的程序内存监控方法,在程序运行过程中,在每个程序脚本后端对象创建时,都需要记录下对应的创建信息与函数调用堆栈数据,并进一步确定对应的托管堆内存信息,对每个程序脚本后端对象创建时托管堆的内存变化进行监控,主要确定哪些对象创建时托管堆需要额外申请内存。同时,在这个过程中,可以通过函数调用堆栈数据来高效定位对象的创建来源,实现监控过程中的对象溯源。而后在每个程序脚本后端对象销毁时,也可以记录下即将被销毁的程序脚本后端对象的对象地址,为程序内存监控提供更多一层的参考。而后可以托管堆内存信息,生成层次结构的托管堆内存分配信息报表以及托管堆内存变化曲线图,托管堆内存信息内包括有各个程序脚本后端对象创建时的时间节点,创建时托管堆的大小、各个基础对象的对象地址以及对象大小等数据,通过托管堆内存分配信息报表以及托管堆内存变化曲线图,可以有效对程序运行过程中托管堆内存的分配情况以及托管堆内存大小的变化情况进行展示,而后在这些报表的基础上面结合对象创建时的调用地址和对象销毁时的销毁信息,来生成可视化报告页面数据,可以更直观地展示出程序运行过程中的内存变化以及引起内存变化的程序脚本后端对象的来源。在其中一个实施例中,内存监控结果的展示过程可以参照图12所示,在这个过程中,首先通过索引表将二进制会进行函数调用堆栈的压缩,获取二进制形式的函数调用堆栈地址列表;而后通过预设符号表将二进制形式的函数调用堆栈地址列表还原为调用地址信息。而后载入处理后的录制数据,包括托管堆内存信息、销毁信息以及解压后的函数调用堆栈数据,并生成echarts形式的托管堆内存变化曲线图以及hierarchy形式的托管堆内存分配信息报表,而后将其转化为html格式的网页页面,写入磁盘以将其展示给用户。在其中一个实施例中,如图13所示,本技术的程序内存监控方法的监控过程在移动终端上实现,而结果展示过程在pc端实现,首先在移动终端上获取原始监控结果,而后将原始监控结果拉取到pc端,而后将其转换为可视化网页后再在pc端进行展示,本实施例中,通过生成层次结构的托管堆内存分配信息报表以及托管堆内存变化曲线图,来对游戏运行过程中的内存监控结果进行展示,可以更直观地对用户展示内存监控的结果,保证程序内存监控的效果。
90.本技术还提供一种应用场景,该应用场景应用上述的程序内存监控方法。具体地,该程序内存监控方法在该应用场景的应用如下:
91.当用户在进行moba(multiplayer online battle arena,多人在线战术竞技游戏)类手游开发时,需要在运行过程中确定游戏程序的内存变化,此时可以在安装该手游的终端上,运用本技术的程序内存监控方法,来实现对程序内存的监控。该手游具体通过unity游戏引擎开发,此时程序脚本后端对象具体为il2cpp对象。终端可以在手游程序运行的时间段时,获取到手游程序对应的虚拟内存变化。本技术的方案实现具体包括两个过程,
包括程序运行时内存数据的监控录制以及录制数据的可视化转换。其中,程序运行时内存数据的监控录制记录步骤,是指在运行游戏的过程中实时记录每一次il2cpp对象的创建和销毁,作为性能分析的数据源。而录制数据可视化转换步骤,是指在将得到的录制数据,通过工具转换为可视化网页的过程,面向用户呈现清晰的结果。具体地,在程序运行时内存数据的监控录制记录步骤中,首先需要在每次il2cpp对象创建时,记录对象分配的大小、地址和函数调用堆栈等数据。因为所有il2cpp对象的创建都会被收敛归纳为三种基础类型的创建,它们分别是object、array、string这三种类型,因此,可以通过分别记录三种基础类型对象的创建,来实现程序脚本后端对象对应的创建信息的记录。而对于函数调用堆栈数据,可以使用frame pointer的堆栈回溯机制来实现,其通过在编译器生成汇编时,将调用者的地址记录到fp寄存器中,从而将堆栈回溯过程变成高效的寄存器值链式读取操作,而在得到函数调用堆栈后,若是直接存储函数调用堆栈的话,内存和磁盘占用会很大。函数调用堆栈的特征是,相同的函数地址可能会高频反复出现。根据该特征,可以使用信息索引法对要记录的函数调用堆栈信息进行压缩。函数调用堆栈压缩完成后,可以记录本次分配ill2cpp对象的大小、类型、地址、函数调用堆栈,同时会调用预设托管堆大小获取函数scripting_gc_get_heap_size来获取此时托管堆的大小,并一并记录下来。而后,il2cpp对象创建出来后是放置在托管堆中的,当需要进行托管堆的内存释放时,托管堆可以通过预设垃圾回收算法会遍历所有存活的对象,找出没有被游戏的业务逻辑所引用的il2cpp对象,然后进行销毁。销毁逻辑真正执行前,会执行一个回调函数,本实施例可以在该回调函数中,记录即将被销毁的il2cpp对象地址,得到销毁信息,以供后续工具链还原内存使用情况时使用。记录完成后,正常执行对象的销毁流程。当运行时录制步骤完成后,记录下来的是不可读的原始结果数据,下一个步骤是用工具对原始结果数据进行可视化转换,通过信息索引法的索引表,将压缩存储的函数调用堆栈索引列表,还原为二进制形式的函数调用堆栈地址列表。然后结合il2cpp和unity的符号表,把二进制函数调用堆栈地址还原为可读的函数名。接下来还可以利用python生成网页,包括hierarchy形式的内存分配信息报表和托管堆内存在测试过程中的曲线图走势,向用户呈现可视化结果,最终得到的可视化展示图具体可以参照图14所示,图14中上半部分为托管堆内存在测试过程中的曲线图,而图14中下半部分为hierarchy形式的内存分配信息报表。
92.应该理解的是,虽然如上的各实施例所涉及的流程图中的各个步骤按照箭头的指示依次显示,但是这些步骤并不是必然按照箭头指示的顺序依次执行。除非本文中有明确的说明,这些步骤的执行并没有严格的顺序限制,这些步骤可以以其它的顺序执行。而且,如上的各实施例所涉及的流程图中的至少一部分步骤可以包括多个步骤或者多个阶段,这些步骤或者阶段并不必然是在同一时刻执行完成,而是可以在不同的时刻执行,这些步骤或者阶段的执行顺序也不必然是依次进行,而是可以与其它步骤或者其它步骤中的步骤或者阶段的至少一部分轮流或者交替地执行。
93.基于同样的发明构思,本技术实施例还提供了一种用于实现上述所涉及的程序内存监控方法的程序内存监控装置。该装置所提供的解决问题的实现方案与上述方法中所记载的实现方案相似,故下面所提供的一个或多个程序内存监控装置实施例中的具体限定可以参见上文中对于程序内存监控方法的限定,在此不再赘述。
94.在一个实施例中,如图14所示,提供了一种程序内存监控装置,包括:
95.创建信息获取模块1502,用于确定程序对应程序脚本后端对象,读取程序脚本后端对象对应的创建信息与函数调用堆栈数据。
96.托管堆信息获取模块1504,用于基于创建信息,确定程序脚本后端对象的托管堆内存信息。
97.销毁信息获取模块1506,用于获取程序对应程序脚本后端对象的销毁信息。
98.监控结果获取模块1508,用于根据托管堆内存信息、销毁信息以及函数调用堆栈数据,获取程序对应的内存监控结果。
99.在其中一个实施例中,托管堆信息获取模块1504具体用于:获取创建信息中的对象大小信息、对象类型信息以及对象地址信息;调用预设托管堆大小获取函数,获取托管堆大小信息;根据对象大小信息、对象类型信息、对象地址信息以及托管堆大小信息,确定程序脚本后端对象的托管堆内存信息。
100.在其中一个实施例中,销毁信息获取模块1506具体用于:通过预设垃圾回收算法遍历托管堆内所有的程序脚本后端对象,确定未被程序业务逻辑引用的程序脚本后端对象;通过预设回调函数记录未被程序业务逻辑引用的程序脚本后端对象的对象地址,获取程序脚本后端对象的销毁信息,对未被程序业务逻辑引用的程序脚本后端对象执行销毁操作。
101.在其中一个实施例中,创建信息获取模块1502具体用于:通过堆栈回溯机制获取函数调用堆栈对应的调用地址信息;通过信息索引法对调用地址信息进行压缩,获取程序对应程序脚本后端对象的函数调用堆栈数据。
102.在其中一个实施例中,监控结果获取模块1508具体用于:将函数调用堆栈数据还原,获取二进制形式的函数调用堆栈地址列表;通过预设符号表将二进制形式的函数调用堆栈地址列表还原为调用地址信息;根据托管堆内存信息、销毁信息以及调用地址信息,获取程序对应的内存监控结果。
103.在其中一个实施例中,监控结果获取模块1508还用于:基于托管堆内存信息,生成层次结构的托管堆内存分配信息报表以及托管堆内存变化曲线图;根据销毁信息、调用地址信息、托管堆内存分配信息报表以及托管堆内存变化曲线图,生成可视化报告页面数据。
104.上述程序内存监控装置中的各个模块可全部或部分通过软件、硬件及其组合来实现。上述各模块可以硬件形式内嵌于或独立于计算机设备中的处理器中,也可以以软件形式存储于计算机设备中的存储器中,以便于处理器调用执行以上各个模块对应的操作。
105.在一个实施例中,提供了一种计算机设备,该计算机设备可以是终端,其内部结构图可以如图16所示。该计算机设备包括通过系统总线连接的处理器、存储器、通信接口、显示屏和输入装置。其中,该计算机设备的处理器用于提供计算和控制能力。该计算机设备的存储器包括非易失性存储介质、内存储器。该非易失性存储介质存储有操作系统和计算机程序。该内存储器为非易失性存储介质中的操作系统和计算机程序的运行提供环境。该计算机设备的通信接口用于与外部的终端进行有线或无线方式的通信,无线方式可通过wifi、移动蜂窝网络、nfc(近场通信)或其他技术实现。该计算机程序被处理器执行时以实现一种程序内存监控方法。该计算机设备的显示屏可以是液晶显示屏或者电子墨水显示屏,该计算机设备的输入装置可以是显示屏上覆盖的触摸层,也可以是计算机设备外壳上设置的按键、轨迹球或触控板,还可以是外接的键盘、触控板或鼠标等。
106.本领域技术人员可以理解,图16中示出的结构,仅仅是与本技术方案相关的部分结构的框图,并不构成对本技术方案所应用于其上的计算机设备的限定,具体的计算机设备可以包括比图中所示更多或更少的部件,或者组合某些部件,或者具有不同的部件布置。
107.在一个实施例中,还提供了一种计算机设备,包括存储器和处理器,存储器中存储有计算机程序,该处理器执行计算机程序时实现上述各方法实施例中的步骤。
108.在一个实施例中,提供了一种计算机可读存储介质,存储有计算机程序,该计算机程序被处理器执行时实现上述各方法实施例中的步骤。
109.在一个实施例中,提供了一种计算机程序产品或计算机程序,该计算机程序产品或计算机程序包括计算机指令,该计算机指令存储在计算机可读存储介质中。计算机设备的处理器从计算机可读存储介质读取该计算机指令,处理器执行该计算机指令,使得该计算机设备执行上述各方法实施例中的步骤。
110.需要说明的是,本技术所涉及的用户信息(包括但不限于用户设备信息、用户个人信息等)和数据(包括但不限于用于分析的数据、存储的数据、展示的数据等),均为经用户授权或者经过各方充分授权的信息和数据。
111.本领域普通技术人员可以理解实现上述实施例方法中的全部或部分流程,是可以通过计算机程序来指令相关的硬件来完成,的计算机程序可存储于一非易失性计算机可读取存储介质中,该计算机程序在执行时,可包括如上述各方法的实施例的流程。其中,本技术所提供的各实施例中所使用的对存储器、数据库或其它介质的任何引用,均可包括非易失性和易失性存储器中的至少一种。非易失性存储器可包括只读存储器(read-only memory,rom)、磁带、软盘、闪存、光存储器、高密度嵌入式非易失性存储器、阻变存储器(reram)、磁变存储器(magnetoresistive random access memory,mram)、铁电存储器(ferroelectric random access memory,fram)、相变存储器(phase change memory,pcm)、石墨烯存储器等。易失性存储器可包括随机存取存储器(random access memory,ram)或外部高速缓冲存储器等。作为说明而非局限,ram可以是多种形式,比如静态随机存取存储器(static random access memory,sram)或动态随机存取存储器(dynamic random access memory,dram)等。本技术所提供的各实施例中所涉及的数据库可包括关系型数据库和非关系型数据库中至少一种。非关系型数据库可包括基于区块链的分布式数据库等,不限于此。本技术所提供的各实施例中所涉及的处理器可为通用处理器、中央处理器、图形处理器、数字信号处理器、可编程逻辑器、基于量子计算的数据处理逻辑器等,不限于此。
112.以上实施例的各技术特征可以进行任意的组合,为使描述简洁,未对上述实施例中的各个技术特征所有可能的组合都进行描述,然而,只要这些技术特征的组合不存在矛盾,都应当认为是本说明书记载的范围。
113.以上实施例仅表达了本技术的几种实施方式,其描述较为具体和详细,但并不能因此而理解为对本技术专利范围的限制。应当指出的是,对于本领域的普通技术人员来说,在不脱离本技术构思的前提下,还可以做出若干变形和改进,这些都属于本技术的保护范围。因此,本技术的保护范围应以所附权利要求为准。
再多了解一些

本文用于企业家、创业者技术爱好者查询,结果仅供参考。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表

相关文献