内存管理方法、装置、存储介质与电子设备
文献发布时间:2023-06-19 09:32:16
技术领域
本公开涉及计算机技术领域,尤其涉及一种内存管理方法、内存管理装置、计算机可读存储介质与电子设备。
背景技术
程序在运行时,需要系统分配内存,来存放程序创建的对象。当某一对象不再被使用时,系统会释放该对象所占的内存,以便分配给新的对象。释放内存的过程称为内存回收或垃圾回收。
相关技术中,通常需要遍历内存中的所有对象,以检测出非存活的对象,回收相应的内存。例如,在JVM(Java Virtual Machine,Java虚拟机)中实现内存回收时,先遍历所有的引用,标记出存活的对象,然后遍历所有对象,清除未标记的对象。然而,这种遍历所有对象的方式,会造成较高的系统性能开销,影响内存的使用效率。
发明内容
本公开提供了一种内存管理方法、内存管理装置、计算机可读存储介质与电子设备,进而至少在一定程度上改善相关技术中内存回收造成较高的系统性能开销的问题。
本公开的其他特性和优点将通过下面的详细描述变得显然,或部分地通过本公开的实践而习得。
根据本公开的第一方面,提供一种内存管理方法,包括:当向内存的第一区域存储新对象时,将所述新对象的信息插入多个队列中的第一队列;其中,所述多个队列用于记录所述第一区域所存储的对象的信息;所述多个队列的任意相邻两个队列中后一队列的容量小于或等于前一队列的容量;当所述多个队列中的任一队列存在溢出时,将所述任一队列的头部信息取出;当所述头部信息所属的对象是存活状态时,将所述头部信息插入所述任一队列的下一队列;当所述头部信息所属的对象是非存活状态时,从所述第一区域中回收所述头部信息所属的对象所占用的内存。
根据本公开的第二方面,提供一种内存管理装置,包括:第一插入单元,用于当向内存的第一区域存储新对象时,将所述新对象的信息插入多个队列中的第一队列;其中,所述多个队列用于记录所述第一区域所存储的对象的信息;所述多个队列的任意相邻两个队列中后一队列的容量小于或等于前一队列的容量;头部信息取出单元,用于如果所述多个队列中的任一队列存在溢出,则将所述任一队列的头部信息取出;第二插入单元,用于当所述头部信息所属的对象是存活状态时,将所述头部信息插入所述任一队列的下一队列;内存回收单元,用于当所述头部信息所属的对象是非存活状态时,从所述第一区域中回收所述头部信息所属的对象所占用的内存。
根据本公开的第三方面,提供一种计算机可读存储介质,其上存储有计算机程序,所述计算机程序被处理器执行时实现上述第一方面的内存管理方法及其可能的实现方式。
根据本公开的第四方面,提供一种电子设备,包括:处理器;以及存储器,用于存储所述处理器的可执行指令;其中,所述处理器配置为经由执行所述可执行指令来执行上述第一方面的内存管理方法及其可能的实现方式。
本公开的技术方案具有以下有益效果:
通过设置多个队列,实现了对第一区域中的内存对象进行分层级管理。每个队列相当于一个层级,当对象的信息每次从队列中被取出时,进行一次对象存活状态的检测,如果对象存活则将其信息插入下一队列,表示该对象晋升一个层级。即,存活时间越长,层级越高。一般的,在第一区域中,对象数量随存活时间的变化呈现衰减或者持平的趋势,即存活时间越长的对象,其数量越少或者持平。而本方案中设置任意相邻两个队列中后一队列的容量小于或等于前一队列的容量,使得队列容量的变化趋势基本符合对象数量的变化趋势。一方面,在每次对象信息被移出队列时进行对象存活状态的检测,更加符合对象本身的生命周期规律,从而优化了对象存活状态检测的时机,无需在回收内存时遍历所有对象,提升内存的使用效率,降低系统性能开销,同时减少了程序的暂停次数,提高了程序运行效率。另一方面,整个流程仅对从队列取出的信息所属的对象进行处理,不影响其他对象在内存中的正常加载,也无需移动其他对象的存储地址,因此进一步提高了内存的使用效率与程序运行效率。
应当理解的是,以上的一般描述和后文的细节描述仅是示例性和解释性的,并不能限制本公开。
附图说明
此处的附图被并入说明书中并构成本说明书的一部分,示出了符合本公开的实施例,并与说明书一起用于解释本公开的原理。显而易见地,下面描述中的附图仅仅是本公开的一些实施例,对于本领域普通技术人员来讲,在不付出创造性劳动的前提下,还可以根据这些附图获得其他的附图。
图1示出本示例性实施方式中一种电子设备的结构图;
图2示出本示例性实施方式中一种内存管理方法的流程图;
图3示出本示例性实施方式中一种队列的示意图;
图4示出本示例性实施方式中一种内存管理方法的子流程图;
图5示出本示例性实施方式中过阻尼振动衰减关系的曲线图;
图6示出本示例性实施方式中一种确定队列容量方法的流程图;
图7示出本示例性实施方式中另一种确定队列容量方法的流程图;
图8示出本示例性实施方式中一种队列容量的示意图;
图9示出本示例性实施方式中一种堆内存管理方法的流程图;
图10示出本示例性实施方式中一种内存管理装置的结构图。
具体实施方式
现在将参考附图更全面地描述示例实施方式。然而,示例实施方式能够以多种形式实施,且不应被理解为限于在此阐述的范例;相反,提供这些实施方式使得本公开将更加全面和完整,并将示例实施方式的构思全面地传达给本领域的技术人员。所描述的特征、结构或特性可以以任何合适的方式结合在一个或更多实施方式中。在下面的描述中,提供许多具体细节从而给出对本公开的实施方式的充分理解。然而,本领域技术人员将意识到,可以实践本公开的技术方案而省略特定细节中的一个或更多,或者可以采用其它的方法、组元、装置、步骤等。在其它情况下,不详细示出或描述公知技术方案以避免喧宾夺主而使得本公开的各方面变得模糊。
此外,附图仅为本公开的示意性图解,并非一定是按比例绘制。图中相同的附图标记表示相同或类似的部分,因而将省略对它们的重复描述。附图中所示的一些方框图是功能实体,不一定必须与物理或逻辑上独立的实体相对应。可以采用软件形式来实现这些功能实体,或在一个或多个硬件模块或集成电路中实现这些功能实体,或在不同网络和/或处理器装置和/或微控制器装置中实现这些功能实体。
相关技术中,基于Java语言的系统通常将堆内存划分为年轻代和老年代,年轻代存放生命周期较短的对象,老年代存放生命周期较长的对象。年轻代与老年代采用不同的内存回收方式:
年轻代的内存回收方式称为Minor GC,具体地,先遍历年轻代中的所有对象,将存活的对象移至年轻代中的一块连续区域,并将这些对象的age(年龄)加1;然后清空年轻代中的其他区域,由此释放非存活对象所在的内存;当某一对象的age达到设定的阈值(如一般设为15)时,将其移至老年代。
老年代的内存回收方式称为Major GC,具体地,先从GC roots(引用关系中的根节点,一般是由堆外指向堆内的引用)开始遍历老年代中的所有引用,标记出存活的引用对象,然后遍历老年代中的所有对象,清除未被标记的对象,释放相应的内存。
可见,无论是年轻代还是老年代,在内存回收中都需要遍历所有对象,由此造成较高的系统性能开销;并且在遍历对象时,可能导致相关的应用程序的暂停。对于年轻代来说,每次回收内存需要移动存活对象,从而进一步增加了性能开销。
鉴于上述问题,本公开的示例性实施方式提供一种内存管理方法,该方法可应用于各种电子设备,包括但不限于计算机、智能手机、平板电脑、游戏机、可穿戴设备等。一般的,电子设备包括处理器和存储器。存储器用于存储处理器的可执行指令,也可以存储应用数据,如图像数据、游戏数据等;存储器包括易失性存储器,通常为RAM(Random AccessMemory,随机存取存储器),也可以包括非易失性存储器,如至少一个磁盘存储器件,闪存器件,UFS(Universal Flash Storage,通用闪存存储器)等;处理器配置为经由执行可执行指令来执行本示例性实施方式中的内存管理方法。内存管理方法所针对的内存可以是上述易失性存储器。
下面以图1中的移动终端100为例,对上述电子设备的构造进行示例性说明。本领域技术人员应当理解,除了特别用于移动目的的部件之外,图1中的构造也能够应用于固定类型的设备。
如图1所示,移动终端100具体可以包括:处理器110、内部存储器121、外部存储器接口122、USB(Universal Serial Bus,通用串行总线)接口130、充电管理模块140、电源管理模块141、电池142、天线1、天线2、移动通信模块150、无线通信模块160、音频模块170、扬声器171、受话器172、麦克风173、耳机接口174、传感器模块180、显示屏190、摄像模组191、指示器192、马达193、按键194以及SIM(Subscriber Identification Module,用户标识模块)卡接口195等。
处理器110可以包括一个或多个处理单元,例如:处理器110可以包括AP(Application Processor,应用处理器)、调制解调处理器、GPU(Graphics ProcessingUnit,图形处理器)、ISP(Image Signal Processor,图像信号处理器)、控制器、编码器、解码器、DSP(Digital Signal Processor,数字信号处理器)、基带处理器和/或NPU(Neural-Network Processing Unit,神经网络处理器)等。
在一些实施方式中,处理器110可以包括一个或多个接口,通过不同的接口和移动终端100的其他部件形成连接。
内部存储器121可以用于存储计算机可执行程序代码,所述可执行程序代码包括指令。内部存储器121可以包括易失性存储器,如DRAM(Dynamic Random Access Memory,动态随机存储器)、SRAM(Static Random Access Memory,静态随机存储器),还可以包括非易失性存储器,例如至少一个磁盘存储器件,闪存器件,UFS等。处理器110通过运行存储在内部存储器121的指令和/或存储在设置于处理器中的存储器的指令,执行移动终端100的各种功能应用以及数据处理。
外部存储器接口122可以用于连接外部存储器,例如Micro SD卡,实现扩展移动终端100的存储能力。外部存储器通过外部存储器接口122与处理器110通信,实现数据存储功能,例如存储音乐,视频等文件。
USB接口130是符合USB标准规范的接口,可以用于连接充电器为移动终端100充电,也可以连接耳机或其他电子设备。
充电管理模块140用于从充电器接收充电输入。充电管理模块140为电池142充电的同时,还可以通过电源管理模块141为设备供电;电源管理模块141还可以监测电池的状态。
移动终端100的无线通信功能可以通过天线1、天线2、移动通信模块150、无线通信模块160、调制解调处理器以及基带处理器等实现。天线1和天线2用于发射和接收电磁波信号。移动通信模块150可以提供应用在移动终端100上的包括2G/3G/4G/5G等无线通信的解决方案。无线通信模块160可以提供应用在移动终端100上的包括WLAN(Wireless LocalArea Networks,无线局域网)(如Wi-Fi(Wireless Fidelity,无线保真)网络)、BT(Bluetooth,蓝牙)、GNSS(Global Navigation Satellite System,全球导航卫星系统)、FM(Frequency Modulation,调频)、NFC(Near Field Communication,近距离无线通信技术)、IR(Infrared,红外技术)等无线通信解决方案。
移动终端100可以通过GPU、显示屏190及AP等实现显示功能,可以通过ISP、摄像模组191、编码器、解码器、GPU、显示屏190及AP等实现拍摄功能,还可以通过音频模块170、扬声器171、受话器172、麦克风173、耳机接口174及AP等实现音频功能。
传感器模块180可以包括深度传感器1801、压力传感器1802、陀螺仪传感器1803、气压传感器1804等,以实现不同的感应检测功能。
指示器192可以是指示灯,可以用于指示充电状态,电量变化,也可以用于指示消息,未接来电,通知等。马达193可以产生振动提示,也可以用于触摸振动反馈等。按键194包括开机键,音量键等。
移动终端100可以支持一个或多个SIM卡接口195,用于连接SIM卡,以实现通话以及数据通信等功能。
图2示出了本示例性实施方式中一种内存管理方法的流程,可以包括:
步骤S210,当向内存的第一区域存储新对象时,将新对象的信息插入多个队列中的第一队列;
步骤S220,如果上述多个队列中的任一队列存在溢出,则将该任一队列的头部信息取出;
步骤S230,当上述头部信息所属的对象是存活状态时,将上述头部信息插入上述任一队列的下一队列;
步骤S240,当上述头部信息所属的对象是非存活状态时,从第一区域中回收上述头部信息所属的对象所占用的内存。
需要说明的是,图2中包含了循环过程,具体为步骤S220与S230的循环,即在执行步骤S230后,如果触发了步骤S220中的条件,则跳转至步骤S220并再次执行。
下面分别对图2中的每个步骤做具体说明。
步骤S210中,当向内存的第一区域存储新对象时,将新对象的信息插入多个队列中的第一队列。
其中,第一区域用于存储程序运行时所需的对象数据。例如,第一区域可以是堆内存,堆内存是区别于栈区、全局数据区和代码区的另一个内存区域,允许程序在运行时动态地申请某个大小的内存空间,以存储对象数据;第一区域也可以是堆内存中的年轻代,用于存储生命周期较短的对象数据。上述预先创建的多个队列,用于记录第一区域所存储的对象的信息。对象的信息并非指对象的全量数据,而是寻址或索引信息,通常包括对象在第一区域中的存储地址,用于快速查找到对象数据。在一种可选的实施方式中,队列中可以存放对象的头信息,包括但不限于对象的存储地址、被引用的信息及其他监控、采样的信息等。由此,系统通过读取队列中的信息,可以快速索引至对象的存储地址,或者确定对象的状态等,非常高效。
上述多个队列可以是从第一区域中或第一区域以外的内存中划分出的专门的空间,本公开对此不做限定。不同队列之间具有固定的先后顺序。任意相邻两个队列中后一队列的容量小于或等于前一队列的容量,即对于任意队列j,其容量C(j)≥C(j+1)。
在向内存的第一区域存储新对象时,可以将新对象的信息插入第一队列。本示例性实施方式中的队列设置为FIFO(First in First out,先入先出)的机制,即从队列的尾部插入新的信息,从队列的头部取出原有信息。因此,新对象的信息被插入至第一队列的尾部,第一队列中的原有信息可以向头部移动一个单位。
继续参考图2,步骤S220中,如果上述多个队列中的任一队列存在溢出,则将该任一队列的头部信息取出。
队列中的信息数量超过容量时,发生溢出。例如,队列本身为满状态,插入一条新的信息时,发生溢出,此时需要取出头部信息,头部信息通常是进入该队列时间最早的一条信息。
步骤S220包括两种情况:第一种情况是在步骤S210中,如果第一队列为满状态,插入新对象的信息时,发生溢出,取出第一队列的头部信息。第二种情况是对于第一队列之后的任一队列,当在满状态下接受从前一队列中取出的头部信息时(通常为执行步骤S230之后),则发生溢出,取出本队列的头部信息。
继续参考图2,步骤S230中,当上述头部信息所属的对象是存活状态时,将上述头部信息插入上述任一队列的下一队列。
队列中的每一条信息均对应于一个对象。将步骤S220中发生溢出的队列记为队列i,其头部信息记为信息k',信息k'所属的对象记为对象k。在从队列i取出信息k'时,需要判断对象k的存活状态,包括但不限于以下方式:
信息k'中包含了对象k被引用的信息,当对象k仍然被其他至少一个对象所引用时,为存活状态,当对象k不被其他任何对象所引用时,为非存活状态。
遍历当前的对象引用图谱,从根节点开始,如果存在到达对象k的引用路径,则确定对象k为存活状态,反之为非存活状态。
如果对象k为存活状态,则将信息k'其插入队列i+1,通常插入队列i+1的尾部。
需要说明的是,如果队列i+1为满状态,插入信息k'后发生溢出,则触发对队列i+1执行步骤S220,即取出队列i+1的头部信息,记为信息h',所属的对象记为对象h。然后判断对象h的存活状态,如果是存活状态,则将信息h'插入队列i+2。如果插入信息h'导致队列i+2的溢出,则再次回到步骤S220。由此实现了循环处理,直到所有队列不存在溢出为止。
图3示出了队列之间的关系,其中顶端表示队列的尾部,底端表示头部,从左向右依次是第一队列、第二队列等等。当前一队列的头部信息被取出时,在判断其所属的对象存活的情况下,该信息被插入后一队列的尾部,由此形成了相邻两队列之间的首尾相连关系,能够实现上述循环处理。
在一种可选的实施方式中,参考图4所示,步骤S230可以包括以下步骤S410和S420:
步骤S410,当上述头部信息所属的对象是存活状态时,判断上述多个队列中是否存在上述任一队列的下一队列;
步骤S420,当上述多个队列中存在上述任一队列的下一队列时,将上述头部信息插入上述任一队列的下一队列。
举例来说,当确定对象k为存活状态时,判断是否存在队列i+1,以确保是否还有队列能够接纳信息k'。具体地,可以判断上述任一队列的序数是否小于上述多个队列中的最大序数,即是否满足i 在一种可选的实施方式中,参考图4所示,还可以执行以下步骤S430: 步骤S430,当上述多个队列中不存在上述任一队列的下一队列时,将上述头部信息所属的对象从第一区域移至内存的第二区域。 换而言之,当队列i为最后一个队列时,将信息k'移至第二区域。 第二区域是用于存储对象的另一区域,其与第一区域的区别为:第一区域中对象的生命周期较短,第二区域中对象的生命周期较长;第二区域采用不同于第一区域的内存回收方式,例如第二区域中内存回收的周期更长。本示例性实施方式中,可以将内存中的数据存储区划分为第一区域和第二区域,设置不同的内存回收方式。也可以基于系统对堆内存的划分,将堆内存的年轻代作为第一区域,老年代作为第二区域。 对象k被存储至第一区域时,其信息k'被插入第一队列,随着后续有其他对象被存储至第一区域,信息k'从第一队列的尾部被逐渐移至头部,然后被取出,同时对对象k执行一次存活状态检测,当对象k存活时,将信息k'插入第二队列,并重复上述移动与取出、检测存活状态的过程。可见,每次信息k'被移出某个队列时,对对象k执行一次存活状态的检测,如果信息k'从最后一个队列移出时,对象k仍然为存活状态,说明对象k经历了n次存活状态检测(n为队列数量),是当前第一区域中存活时间最长的对象,将其移至第二区域中,以便于更好地管理。 继续参考图2,步骤S240中,当上述头部信息所属的对象是非存活状态时,从第一区域中回收上述头部信息所属的对象所占用的内存。 通过头部信息可以确定其所属的对象在第一区域中的存储地址,然后将该地址中所存储的对象删除,释放相应的内存区域,实现内存回收。 在一种可选的实施方式中,在回收头部信息所属的对象所占用的内存时,还可以删除该头部信息,即从第一区域中删除对象时,也同步地从队列中删除对象的信息,以释放队列中的空间,便于容纳其他对象的信息。 本示例性实施方式中,通过设置多个队列,实现了对第一区域中的内存对象进行分层级管理。每个队列相当于一个层级,当对象的信息每次从队列中被取出时,进行一次对象存活状态的检测,如果对象存活则将其信息插入下一队列,表示该对象晋升一个层级。即,存活时间越长,层级越高。一般的,在第一区域中,对象数量随存活时间的变化呈现衰减或者持平的趋势,即存活时间越长的对象,其数量越少或者持平。而本方案中设置任意相邻两个队列中后一队列的容量小于或等于前一队列的容量,使得队列容量的变化趋势基本符合对象数量的变化趋势。一方面,在每次对象信息被移出队列时进行对象存活状态的检测,更加符合对象本身的生命周期规律,从而优化了对象存活状态检测的时机,无需在回收内存时遍历所有对象,提升内存的使用效率,降低系统性能开销,同时减少了程序的暂停次数,提高了程序运行效率。另一方面,整个流程仅对从队列取出的信息所属的对象进行处理,不影响其他对象在内存中的正常加载,也无需移动其他对象的存储地址,因此进一步提高了内存的使用效率与程序运行效率。 本示例性实施方式中,按照队列的排布顺序,其容量呈现出递减或持平的变化趋势,该趋势与对象数量随存活时间的变化趋势相匹配。由此,可以按照对象数量的变化趋势设置队列的容量。 一般的,第一队列的容量最大,最后一个队列的容量最小。在一些特殊情况下,对象数量随存活时间的变化保持稳定,则可以设置第一队列的容量与最后一个队列的容量相同,这意味着所有队列的容量均相同。 在一种可选的实施方式中,对象数量随存活时间的变化为整体上递减、局部平缓,则可以设置第一队列的容量大于最后一个队列的容量。 在一种可选的实施方式中,对象数量随存活时间的变化为全部区间均递减,则可以设置各队列的容量依次递减,即对于任意队列j,其容量C(j)>C(j+1)。 在一种可选的实施方式中,可以基于预先确定的衰减关系,确定上述多个队列中每个队列的容量,使每个队列的序数与容量满足该衰减关系。这里的衰减关系可以是对象数量随存活时间的衰减关系。在不同的电子设备运行场景或系统环境中,上述衰减关系都有可能不同,例如可以是过阻尼振动衰减关系、多项式衰减关系。通过对实际运行过程中,第一区域内的对象存活时间和对象数量进行采样。例如,监测一段运行时间内每个对象的存活时间,然后统计不同存活时间对应的对象数量,采样形成多个数据点;将数据点标注在存活时间-对象数量的坐标系中,再通过函数拟合,得到拟合曲线,该曲线的衰减关系即所需的衰减关系。 在一种可选的实施方式中,上述衰减关系可以是过阻尼振动衰减关系。过阻尼振动属于阻尼振动的一种形式,使用机械振动的简谐系统,可以将振动关系表示如下:
其中,x为振幅,t为时间, 利用过阻尼振动衰减关系可以设置不同队列的容量。在一种可选的实施方式中,参考图6所示,可以通过执行以下步骤S610和S620来实现: 步骤S610,根据预先确定的固有频率和阻尼因子,建立用于表示过阻尼振动衰减关系的函数; 步骤S620,通过上述函数计算每个队列的容量。 过阻尼振动衰减关系的函数可以参考式(1),其中包含有固有频率ω 在一种可选的实施方式中,可以通过采样与拟合确定参数。具体来说,对第一区域中的对象存活时间和对象数量进行采样,如可以将采样数据绘制在存活时间-对象数量的坐标系中,并基于过阻尼振动衰减关系对采样数据进行拟合,根据拟合的结果得到曲线参数,即固有频率和阻尼因子。 需要说明的是,拟合时可能得到多个相近的结果,可以利用固有频率小于阻尼因子的条件(即过阻尼振动的条件)进行筛选,一般可以保留符合固有频率小于阻尼因子的条件且拟合误差最小的结果。 为了提高拟合效率,可以对固有频率和阻尼因子设置初始值或者数值范围,作为拟合的参考信息,以减小拟合处理的计算量,并提高拟合的准确度。 在上述拟合中,采用存活时间-对象数量的坐标系,为了确定队列的容量,需要将存活时间与队列的序数之间建立映射。 在一种可选的实施方式中,可以在拟合的阶段建立映射。具体来说,在对第一区域中的对象存活时间和对象数量进行采样时,可以将对象存活时间进行离散化处理,得到分别与每个队列的序数相对应的离散化时间段,由此得到队列序数-对象数量的采样数据,从而可以拟合出队列序数-对象数量的衰减曲线,并得到固有频率和阻尼因子。这样在确定队列容量时,可以根据预先确定的固有频率和阻尼因子,建立以每个队列的序数为自变量,以每个队列的容量为因变量的函数,进而通过该函数直接计算出队列序数为1、2、3等数值时,对应的对象数量,即队列的容量。 在一种可选的实施方式中,可以在拟合的阶段仍然对存活时间-对象数量的衰减关系进行拟合,得到固有频率和阻尼因子。进而通过图7所示的过程实现队列容量的确定,包括: 步骤S710,根据预先确定的固有频率和阻尼因子,建立以对象存活时间为自变量,以对象数量为因变量的函数; 步骤S720,将对象存活时间进行离散化处理,得到分别与每个队列的序数相对应的离散化时间段; 步骤S730,将离散化时间段代入上述函数,计算每个队列的容量。 在进行离散化处理时,可以采用均匀离散化的方式,例如设置100ms的单位时间,将0~100ms的离散化时间段对应于队列序数1,100~200ms的离散化时间段对应于队列序数2,这样不同时间段的跨度是相同的;也可以采用非均匀离散化的方式,一般队列序数越低的离散化时间段,跨度越小,例如0~100ms对应队列序数1,100~250ms对应队列序数2,250~500ms对应队列序数3,等等。具体采用哪种方式,可以视实际情况而定,本公开不做限定。 步骤S710中建立的函数自变量为对象存活时间,经过离散化处理,将不同时间段对应到不同的队列序数,由此将函数的自变量映射为队列序数;然后将离散化时间段代入上述函数,一般可以代入时间段的中值,计算因变量,并取整,得到队列的容量,也可以代入左右两端点值,对中间结果取整。 图8示出了根据过阻尼振动衰减关系确定的队列容量的示意图,将表示时间的横坐标进行离散化处理后,得到离散化时间段,每个离散化时间段对应于一个队列序数,从1开始递增,表示对象数量的纵坐标可以直接映射为队列容量。可以看出,前期队列容量下降得很快,随着序数逐渐增加,下降趋势变缓,最后趋于平缓,接近于保持稳定。 在一种可选的实施方式中,可以根据内存中第一区域的大小,计算所能存储的对象的总数量,对象的总数量可以等同于全部队列的总容量,并由此进一步计算出队列的数量。 在一种可选的实施方式中,也可以结合实际需求设置队列数量,例如在JVM中通常将年轻代的年龄阈值设为15,本示例性实施方式中如何以堆内存的年轻代作为第一区域,则可以将队列的数量设为15,以符合对象的衰减规律。由此可见,本示例性实施方式通过设置多个队列,实现对象的多层级管理,相当于对对象设置了不同的年龄,但是本示例性实施方式无需记录与处理每个对象的年龄,通过将对象信息不断向后面的队列移动,实现了分年龄段来管理的效果,非常高效。 需要补充的是,本示例性实施方式可以设置上述采样的时间,例如按照固定的周期,或者在满足预设的触发条件时(通常为系统运行状态发生变更时,如开始或停止运行大型程序,系统环境变化,内存参数变化等),对内存中对象的存活时间进行监测采样,并通过拟合更新衰减关系中的参数,如上述固有频率和阻尼因子,从而更新队列的容量或数量,以实现队列的动态更新,更好地适应系统运行状态的变化,提高效率。 图9示出了本示例性实施方式中一种堆内存管理方法的流程图,以内存中存入一个新对象的处理过程为一个流程,包括: 步骤S910,内存中存储新对象时,存入年轻代,此时新对象的信息还未插入任何队列,设置其队列序数i=0。 步骤S920,判断待插入队列的信息的队列序数是否小于队列总数n,若否,则执行步骤S930,若是,则执行步骤S940。 步骤S930,将待插入队列的信息所属的对象移至老年代,本次流程结束。 步骤S940,将待插入队列的信息插入队列i+1。 步骤S950,判断队列i+1是否发生溢出,若否,则本次流程结束,若是,则执行步骤S960。 步骤S960,将队列i+1的头部信息移出队列。 步骤S970,判断该头部信息所属的对象是否存活,若否,则执行步骤S980,若是,则跳转至步骤S920,开始下一轮循环。 步骤S980,删除头部信息所属的对象,释放其所占的内存,完成内存回收,本次流程结束。 通过上述方法,以内存中每次存入新对象为触发,对不同队列的头部信息所属的对象进行管理,以回收非存活对象所占的内存,实现内存的有效利用。 本公开的示例性实施方式还提供一种内存管理装置。参考图10所示,该内存管理装置1000可以包括: 第一插入单元1010,用于当向内存的第一区域存储新对象时,将新对象的信息插入多个队列中的第一队列;其中,上述多个队列用于记录第一区域所存储的对象的信息;上述多个队列的任意相邻两个队列中后一队列的容量小于或等于前一队列的容量; 头部信息取出单元1020,用于如果上述多个队列中的任一队列存在溢出,则将该任一队列的头部信息取出; 第二插入单元1030,用于当上述头部信息所属的对象是存活状态时,将上述头部信息插入上述任一队列的下一队列; 内存回收单元1040,用于当上述头部信息所属的对象是非存活状态时,从第一区域中回收上述头部信息所属的对象所占用的内存。 在一种可选的实施方式中,第二插入单元1030,被配置为: 当上述头部信息所属的对象是存活状态时,判断上述多个队列中是否存在上述任一队列的下一队列; 当上述多个队列中存在上述任一队列的下一队列时,将头部信息插入上述任一队列的下一队列。 在一种可选的实施方式中,第二插入单元1030,被配置为: 判断上述任一队列的序数是否小于上述多个队列中的最大序数,若是,则确定上述多个队列中存在上述任一队列的下一队列。 在一种可选的实施方式中,第二插入单元1030,还被配置为: 当上述多个队列中不存在上述任一队列的下一队列时,将上述头部信息所属的对象从第一区域移至内存的第二区域。 在一种可选的实施方式中,上述第一区域包括年轻代,上述第二区域包括老年代。 在一种可选的实施方式中,内存管理装置1000还可以包括队列管理单元,被配置为: 基于预先确定的衰减关系,确定多个队列中每个队列的容量,使每个队列的序数与容量满足衰减关系。 在一种可选的实施方式中,上述衰减关系包括过阻尼振动衰减关系。 在一种可选的实施方式中,队列管理单元,被配置为: 根据预先确定的固有频率和阻尼因子,建立用于表示过阻尼振动衰减关系的函数; 通过上述函数计算每个队列的容量。 在一种可选的实施方式中,队列管理单元,被配置为: 根据预先确定的固有频率和阻尼因子,建立以每个队列的序数为自变量,以每个队列的容量为因变量的函数。 在一种可选的实施方式中,队列管理单元,被配置为: 根据预先确定的固有频率和阻尼因子,建立以对象存活时间为自变量,以对象数量为因变量的函数; 将对象存活时间进行离散化处理,得到分别与每个队列的序数相对应的离散化时间段; 将离散化时间段代入上述函数,计算每个队列的容量。 在一种可选的实施方式中,队列管理单元,被配置为: 对第一区域中的对象存活时间和对象数量进行采样,并基于过阻尼振动衰减关系对采样数据进行拟合,得到固有频率和阻尼因子,固有频率小于阻尼因子。 在一种可选的实施方式中,内存回收单元1040,被配置为: 在从第一区域中回收上述头部信息所属的对象所占用的内存时,删除上述头部信息。 在一种可选的实施方式中,上述新对象的信息包括新对象的头信息。 在一种可选的实施方式中,上述第一区域包括堆内存。 在一种可选的实施方式中,上述多个队列中的第一队列的容量大于最后一个队列的容量。 上述装置中各部分的具体细节在方法部分实施方式中已经详细说明,因而不再赘述。 本公开的示例性实施方式还提供了一种计算机可读存储介质,可以实现为程序产品的形式,包括程序代码,当程序产品在终端设备上运行时,程序代码用于使终端设备执行本说明书上述“示例性方法”部分中描述的根据本公开各种示例性实施方式的步骤,例如可以执行图2、图4、图6、图7或图9中任意一个或多个步骤。该程序产品可以采用便携式紧凑盘只读存储器(CD-ROM)并包括程序代码,并可以在终端设备,例如个人电脑上运行。然而,本公开的程序产品不限于此,在本文件中,可读存储介质可以是任何包含或存储程序的有形介质,该程序可以被指令执行系统、装置或者器件使用或者与其结合使用。 程序产品可以采用一个或多个可读介质的任意组合。可读介质可以是可读信号介质或者可读存储介质。可读存储介质例如可以为但不限于电、磁、光、电磁、红外线、或半导体的系统、装置或器件,或者任意以上的组合。可读存储介质的更具体的例子(非穷举的列表)包括:具有一个或多个导线的电连接、便携式盘、硬盘、随机存取存储器、只读存储器(ROM)、可擦式可编程只读存储器(EPROM或闪存)、光纤、便携式紧凑盘只读存储器(CD-ROM)、光存储器件、磁存储器件、或者上述的任意合适的组合。 计算机可读信号介质可以包括在基带中或者作为载波一部分传播的数据信号,其中承载了可读程序代码。这种传播的数据信号可以采用多种形式,包括但不限于电磁信号、光信号或上述的任意合适的组合。可读信号介质还可以是可读存储介质以外的任何可读介质,该可读介质可以发送、传播或者传输用于由指令执行系统、装置或者器件使用或者与其结合使用的程序。 可读介质上包含的程序代码可以用任何适当的介质传输,包括但不限于无线、有线、光缆、RF等等,或者上述的任意合适的组合。 可以以一种或多种程序设计语言的任意组合来编写用于执行本公开操作的程序代码,程序设计语言包括面向对象的程序设计语言—诸如Java、C++等,还包括常规的过程式程序设计语言—诸如“C”语言或类似的程序设计语言。程序代码可以完全地在用户计算设备上执行、部分地在用户设备上执行、作为一个独立的软件包执行、部分在用户计算设备上部分在远程计算设备上执行、或者完全在远程计算设备或服务器上执行。在涉及远程计算设备的情形中,远程计算设备可以通过任意种类的网络,包括局域网(LAN)或广域网(WAN),连接到用户计算设备,或者,可以连接到外部计算设备(例如利用因特网服务提供商来通过因特网连接)。 本领域技术人员能够理解,本公开的各个方面可以实现为系统、方法或程序产品。因此,本公开的各个方面可以具体实现为以下形式,即:完全的硬件实施方式、完全的软件实施方式(包括固件、微代码等),或硬件和软件方面结合的实施方式,这里可以统称为“电路”、“模块”或“系统”。 本领域技术人员在考虑说明书及实践这里公开的发明后,将容易想到本公开的其他实施方式。本公开旨在涵盖本公开的任何变型、用途或者适应性变化,这些变型、用途或者适应性变化遵循本公开的一般性原理并包括本公开未公开的本技术领域中的公知常识或惯用技术手段。说明书和实施方式仅被视为示例性的,本公开的真正范围和精神由权利要求指出。 应当理解的是,本公开并不局限于上面已经描述并在附图中示出的精确结构,并且可以在不脱离其范围进行各种修改和改变。本公开的范围仅由所附的权利要求来限定。
- 内存管理方法、装置、电子设备及存储介质
- 内存管理方法、装置、电子设备以及存储介质