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

内存管理方法、装置、设备及计算机可读存储介质与流程

2022-12-20 20:15:58 来源:中国专利 TAG:


1.本技术涉及内存管理技术,尤其涉及一种方法、装置、设备及计算机可读存储介质。


背景技术:

2.在程序开发过程中,当删除之前创建的对象时,只会删除变量的引用,并不会立即清除占用的内存空间,失去引用的对象就成了内存中的垃圾。垃圾收集(gc,garbage collection)是java语言的核心技术之一。在进行垃圾收集或者说进行垃圾回收时,一般采用标记清除机制来实现,也即先标记出可访问的对象,然后再遍历堆,把未标记的对象回收。在相关技术中,在标记阶段采用标记入栈方式进行对象图的标记,通常由一组根对象指针的集合出发,遍历整个对象图,会出现无效内存访问,从而降低内存管理效率。


技术实现要素:

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.在一些实施例中,该装置还包括:
32.移位模块,用于将所述对象节点的对象指针按照所述起始位数进行右向移位操作,得到所述深度编码信息;
33.第三确定模块,用于将所述深度编码信息的十进制值确定为所述对象节点的编码深度。
34.在一些实施例中,该第一标记模块,还用于:
35.当基于所述深度编码信息确定所述对象节点的编码深度低于预设的深度阈值时,确定该对象节点是否为叶子节点;
36.当所述对象节点不为叶子节点时,获取并标记所述对象节点的子对象节点;
37.获取所述子对象节点的编码深度;
38.当所述子对象节点的编码深度小于所述对象节点的编码深度时,按照所述预设遍历方式标记所述子对象节点的子对象节点直至标记至叶子节点。
39.在一些实施例中,该装置还包括:
40.第一入栈模块,用于当所述子对象节点的编码深度大于或者等于所述对象节点的编码深度时,将标记后的所述子对象节点增加至所述标记栈。
41.在一些实施例中,该装置还包括:
42.第四获取模块,用于当基于所述深度编码信息确定所述对象节点的编码深度不低于预设的深度阈值时,获取所述对象节点的子对象节点;
43.第三标记模块,用于如果所述子对象节点未被标记,标记所述子对象子节点;
44.第二入栈模块,用于将标记后的所述子对象节点增加至所述标记栈。
45.在一些实施例中,该装置还包括:
46.第五获取模块,用于获取所述堆物理内存的内存信息;
47.映射模块,用于基于多重映射技术、所述内存信息和所述起始位数,将所述堆物理内存映射到不同深度编码信息对应的虚拟内存中。
48.本技术实施例提供一种内存管理设备,包括:
49.存储器,用于存储可执行指令;
50.处理器,用于执行所述存储器中存储的可执行指令时,实现本技术实施例提供的内存管理方法。
51.本技术实施例提供一种计算机可读存储介质,存储有可执行指令,用于引起处理器执行时,实现本技术实施例提供的内存管理方法。
52.本技术实施例具有以下有益效果:
53.在在确定达到内存管理时机时,从标记栈中获取对象节点的对象指针,所述对象指针中包括所述对象节点的深度编码信息;在内存管理的标记阶段,会基于深度编码信息,进行不同的标记处理,其中当所述深度编码信息低于预设的深度阈值时,按照预设的遍历方式标记所述根对象节点的子对象节点直至标记至叶子节点,之后继续对所述标记栈中其他对象节点的子对象进行标记,直至所述标记栈为空,然后在清理阶段基于标记出的对象节点确定未标记的目标对象节点,删除所述目标对象节点,以释放目标对象节点对应的内存空间;如此,对于深度编码信息低于深度阈值的浅遍历对象的子对象节点不再进行入栈出栈的操作而是直接标记,不仅能够减少出栈入栈时间,还能够减少对内存访问以及其入栈所需的栈空间,从而提升内存管理的标记速度,进而提高内存管理效率。
附图说明
54.图1是本技术实施例提供的内存管理系统架构的一个可选的结构示意图;
55.图2是本技术实施例提供的内存管理装置的结构示意图;
56.图3是本技术实施例提供的内存管理方法的一种实现流程示意图;
57.图4为本技术实施例提供的内存管理方法的另一种实现流程示意图;
58.图5为本技术实施例提供的内存管理方法的再一种实现流程示意图;
59.图6a为本技术实施例提供的对象指针的颜色编码设计示意图;
60.图6b为本技术实施例提供的对象指针的分类示意图;
61.图7为本技术实施例提供的让物理内存映射到不同虚拟内存的示意图;
62.图8为本技术实施例提供的运行时在对象分配时添加遍历深度的逻实现流程示意图;
63.图9为本技术实施例提供的内存管理中标记阶段的实现流程示意图。
具体实施方式
64.为了使本技术的目的、技术方案和优点更加清楚,下面将结合附图对本技术作进一步地详细描述,所描述的实施例不应视为对本技术的限制,本领域普通技术人员在没有
做出创造性劳动前提下所获得的所有其它实施例,都属于本技术保护的范围。
65.在以下的描述中,涉及到“一些实施例”,其描述了所有可能实施例的子集,但是可以理解,“一些实施例”可以是所有可能实施例的相同子集或不同子集,并且可以在不冲突的情况下相互结合。
66.在以下的描述中,所涉及的术语“第一\第二\第三”仅仅是是区别类似的对象,不代表针对对象的特定排序,可以理解地,“第一\第二\第三”在允许的情况下可以互换特定的顺序或先后次序,以使这里描述的本技术实施例能够以除了在这里图示或描述的以外的顺序实施。
67.除非另有定义,本文所使用的所有的技术和科学术语与属于本技术的技术领域的技术人员通常理解的含义相同。本文中所使用的术语只是为了描述本技术实施例的目的,不是旨在限制本技术。
68.对本技术实施例进行进一步详细说明之前,对本技术实施例中涉及的名词和术语进行说明,本技术实施例中涉及的名词和术语适用于如下的解释。
69.1)颜色指针(colored pointer),在指针不使用的bit中编码带有其他意义的颜色的指针;
70.2)类是现实世界或思维世界中的实体在计算机中的反映,它将数据以及这些数据上的操作封装在一起。
71.3)对象是具有类类型的变量。
72.类(class)和对象(object)是两种以计算机为载体的计算机语言的合称。对象是对客观事物的抽象,类是对对象的抽象。类是一种抽象的数据类型。它们的关系是,对象是类的实例,类是对象的模板。对象是通过new classname产生的,用来调用类的方法。
73.为了更好地理解本技术实施例提供的内存管理方法,首先对相关技术中的基于垃圾回收机制的内存管理方法及存在的缺点进行说明。
74.当前所有基于追踪(tracing)的内存管理算法(gc算法)均采用标记入栈方式进行对象图的标记,通常由一组根对象指针的集合出发,遍历整个对象图,在处理当前对象的孩子节点时,均使用统一的标记策略,并不区分叶子节点(浅递归对象)和普通对象。无论是当前热点(hotspot)java虚拟机(jvm,java virtual machine)中的(cms,concurrent mark sweep)、(g1,garbage first)、zgc(z garbage collector)等,还是art runtime中的concurrent copying,或者go语言的cms算法等,其mark过程均保持和上述mark过程相同的逻辑,区别在于其各自的处理器过程做了部分cache优化和并行化优化,但是对于每个对象指针的孩子节点的处理逻辑保持一致,对浅递归对象和普通对象均不做区分。
75.相关技术中的内存管理方法主要存在以下缺点:
76.一、经典的mark算法没有区分浅递归对象节点和普通对象节点,在标记过程中需要把浅遍历对象节点压入标记栈(mark stack)中,并在后续阶段从mark stack取出,这样浅遍历对象节点需要经过入栈和出栈操作,增加了mar k阶段的工作量,消耗了mark阶段的cpu资源以及mark stack的内存资源。同时对于浅遍历对象,特别是叶子节点(遍历深度为0的子对象指针)也需要访问其孩子节点信息,而访问孩子节点信息通常需要两次内存跳转(从对象指针对应的内存中拿到对象的类信息指针,再从类信息指针对应的内存中拿到孩子节点信息,即pointers(ref)操作,需要两次内存跳转访问,其对cpu cac he的缓存局部
性是一种破坏,且对叶子节点对象来说这部分内存访问属于无效内存访问。
77.二、经过优化的mark算法可以在mark阶段读取对象的类信息中的孩子节点信息,来判断该对象是否为浅遍历对象,从而减少浅遍历对象的入栈和出栈。但是对于浅遍历对象和普通对象均需要进行内存读取来判断其类型(是否为浅遍历对象),增加了内存访问开销,而这个内存访问和前述内存访问一样需要两次内存的间接跳转,管理效率差。
78.本技术实施例提供一种内存管理方法、装置、设备和计算机可读存储介质,能够通过分配对象阶段增加一个轻微的遍历信息编码操作,以换取mark阶段浅遍历对象的高效识别,从而实现更为高效的mark过程,提升gc的效率。
79.下面说明本技术实施例提供的内存管理设备的示例性应用,本技术实施例提供的设备可以实施为笔记本电脑,平板电脑,台式计算机,机顶盒,移动设备(例如,移动电话,便携式音乐播放器,个人数字助理,专用消息设备,便携式游戏设备)等各种类型的用户终端,也可以实施为服务器。下面,将说明设备实施为服务器时示例性应用。
80.参见图1,图1是本技术实施例提供的网络系统100的架构示意图,如图1所示,该网络系统100包括终端200、网络300和服务器400,终端200通过网络300连接服务器400,网络300可以是广域网或者局域网,又或者是二者的组合。
81.终端200上安装有多个应用程序,例如可以是即时通讯应用程序、购物应用程序、视频观看应用程序等,终端200通过网络与服务器400进行数据交互,服务器400上可以运行有语言虚拟机,本技术实施例提供的内存管理方法可以应用于基于追踪的语言虚拟机运行时的内存管理模块中,服务器400中的语言虚拟机在创建对象时,会获取新创建对象的遍历深度,并将遍历深度编码至对象指针高位未使用的bite位,在启动内存管理时,在marking阶段,将标记栈(mark stack)中取出的对象节点指针进行移位操作以得到对象的遍历深浅信息,移位操作相对于内存读取操作的开销近乎为零,从而实现更低成本的浅遍历对象的识别,并即时进行深度优先(dfs,depth-first-search)遍历处理,避免该类对象的入栈和出栈,降低mark stack的内存消耗以及进出mark stack的cpu消耗;对于叶子节点对象指针,可直接通过移位得知其无孩子节点,无须访问其孩子节点信息,消除了对叶子节点的两次内存间接访问,从而有效的降低marking阶段的内存访问相关的cpu消耗。
82.本技术实施例提供的内存管理方法,可以应用于大数据领域,如各类java大数据应用hadoop、hbase、zookeeper等,此类应用通常使用的堆较大,会缓存很多的数据信息,如zookeeper中通常会缓存大量的配置型信息,这些配置信息通常以字符串(string)的形式存在。而java语言中string对象仅包含一个byte[]对象,如果gc需要遍历string对象开始的对象树,只需要向下遍历一层就可以到达叶子节点byte[]对象,因此string为浅遍历对象。由此可见,在gc marking阶段,如果对像string这样的浅遍历对象直接进行dfs遍历标记的话,可以减少string本身和孩子节点byte[]数组的出栈和入栈,从而极大的降低gc的mark时间和mark stack的内存消耗。
[0083]
在一些实施例中,服务器400可以是独立的物理服务器,也可以是多个物理服务器构成的服务器集群或者分布式系统,还可以是提供云服务、云数据库、云计算、云函数、云存储、网络服务、云通信、中间件服务、域名服务、安全服务、cdn、以及大数据和人工智能平台等基础云计算服务的云服务器。服务器400可以是智能手机、平板电脑、笔记本电脑、台式计算机、智能音箱、智能手表等,但并不局限于此。终端以及服务器可以通过有线或无线通信
方式进行直接或间接地连接,本发明实施例中不做限制。
[0084]
参见图2,图2是本技术实施例提供的服务器400的结构示意图,图2所示的服务器400包括:至少一个处理器410、存储器440、至少一个网络接口420。服务器400中的各个组件通过总线系统430耦合在一起。可理解,总线系统430用于实现这些组件之间的连接通信。总线系统430除包括数据总线之外,还包括电源总线、控制总线和状态信号总线。但是为了清楚说明起见,在图2中将各种总线都标为总线系统430。
[0085]
处理器410可以是一种集成电路芯片,具有信号的处理能力,例如通用处理器、数字信号处理器(dsp,digital signal processor),或者其他可编程逻辑器件、分立门或者晶体管逻辑器件、分立硬件组件等,其中,通用处理器可以是微处理器或者任何常规的处理器等。
[0086]
存储器440可以是可移除的,不可移除的或其组合。示例性的硬件设备包括固态存储器,硬盘驱动器,光盘驱动器等。存储器440可选地包括在物理位置上远离处理器410的一个或多个存储设备。
[0087]
存储器440包括易失性存储器或非易失性存储器,也可包括易失性和非易失性存储器两者。非易失性存储器可以是只读存储器(rom,read only memory),易失性存储器可以是随机存取存储器(ram,random access memor y)。本技术实施例描述的存储器440旨在包括任意适合类型的存储器。
[0088]
在一些实施例中,存储器440能够存储数据以支持各种操作,这些数据的示例包括程序、模块和数据结构或者其子集或超集,下面示例性说明。
[0089]
操作系统441,包括用于处理各种基本系统服务和执行硬件相关任务的系统程序,例如框架层、核心库层、驱动层等,用于实现各种基础业务以及处理基于硬件的任务;
[0090]
网络通信模块442,用于经由一个或多个(有线或无线)网络接口420到达其他计算设备,示例性的网络接口420包括:蓝牙、无线相容性认证(wifi)、和通用串行总线(usb,universal serial bus)等;
[0091]
在一些实施例中,本技术实施例提供的装置可以采用软件方式实现,图2示出了存储在存储器440中的内存管理装置443,其可以是程序和插件等形式的软件,包括以下软件模块:第一获取模块4431、第一标记模块4432、第二标记模块4433和清理模块4434,这些模块是逻辑上的,因此根据所实现的功能可以进行任意的组合或进一步拆分。
[0092]
将在下文中说明各个模块的功能。
[0093]
在另一些实施例中,本技术实施例提供的装置可以采用硬件方式实现,作为示例,本技术实施例提供的装置可以是采用硬件译码处理器形式的处理器,其被编程以执行本技术实施例提供的内存管理方法,例如,硬件译码处理器形式的处理器可以采用一个或多个应用专用集成电路(asic,application specific integrated circuit)、dsp、可编程逻辑器件(pld,programmable logic device)、复杂可编程逻辑器件(cpld,complex programmable logic device)、现场可编程门阵列(fpga,field-programmable gate array)或其他电子元件。
[0094]
将结合本技术实施例提供的终端的示例性应用和实施,说明本技术实施例提供的内存管理方法。
[0095]
参见图3,图3是本技术实施例提供的内存管理方法的一种实现流程示意图,将结
合图3示出的步骤进行说明。
[0096]
步骤s101,在确定达到内存管理时机时,从标记栈中获取对象节点的对象指针。
[0097]
在本技术实施例中,当内存剩余空间小于预设的空间阈值时可以认为达到内存管理时机,还可以提前预设进行内存管理的间隔时长,当当前时刻与上次内存管理时刻之间的时长达到间隔时长时,确定达到内存管理时机。在本技术实施例中,达到内存管理时机时,确定根对象节点集合,并将各个根对象节点进行标记,然后加入到标记栈。然后再从标记栈中依次取出对象节点,以对标记栈中对象节点的子对象节点进行标记处理。
[0098]
其中,对象指针中包括所述对象节点的深度编码信息。在一些实施例中,深度编码信息也称为颜色编码信息,具有颜色编码的对象指针也可以称为颜色指针。在实现时,可以将对象节点的遍历深度编码至对象指针未使用的高位比特位。例如对象指针一共有64位,对象指针占用32位,也就是说对象指针占用了0到31的比特位,32至63为未占用的高位比特位,那么可以从32至63比特位中选择若干个比特位来编码对象节点的遍历深度。需要说明的是,这里的遍历深度可以是基于实际深度和预设的深度阈值确定的,例如是将对象指针未使用的高位比特位中的两个比特位来编码对象节点的深度信息,那么深度编码信息可以是00、01、10和11,对应地,遍历深度可以是0、1、2、3。
[0099]
步骤s102,当基于所述深度编码信息确定所述对象节点的编码深度低于预设的深度阈值时,按照预设的遍历方式标记所述根对象节点的子对象节点直至标记至叶子节点。
[0100]
在本技术实施例中,可以通过将对象指针进行右移位操作,得到对象节点的深度编码信息,然后再确定深度编码信息的十进制数,也就得到了对象节点的编码深度。例如,对象指针为0x1000abcd0000,该对象指针的第44位和第45位为深度编码信息所在比特位,也就是说深度编码信息的起始位数为44,那么将该对象指针右移44位,即可得到深度编码信息,也即为01,对应的十进制数为2,也即该对象指针的遍历深度为2。
[0101]
在本技术实施例中,深度阈值是基于深度编码信息占用的比特位数确定的,例如深度编码信息占用的比特位数为2,那么深度阈值为2
2-1,也即为3。
[0102]
当编码深度小于深度阈值时,说明该对象节点为浅遍历对象,此时不需要将该对象节点的子对象节点再进行标记、入栈、出栈的操作,而是基于类关系图,直接对该对象节点的子对象节点按照预设的遍历方式进行遍历标记,直至将以该对象节点为起始节点的子对象节点标记完,也即直至标记到叶子节点。
[0103]
步骤s103,基于所述标记栈中其他对象节点的深度编码信息对所述其他对象节点的子对象进行标记,直至所述标记栈为空。
[0104]
在完成对该对象节点的子对象节点的标记后,从标记栈中将其他节点进行出栈,并按照步骤s102相同的方式,基于该其他对象节点的深度编码信息对其他对象节点的子对象节点进行标记,直至标记完标记栈中所有对象节点。
[0105]
步骤s104,基于标记出的对象节点确定未标记的目标对象节点,删除所述目标对象节点,以释放目标对象节点对应的内存空间。
[0106]
对象节点为存活的节点,对象节点的子对象节点为引用该对象节点引用的对象,因此也是存活的节点,在通过上述步骤s101至步骤s103完成对存活对象的标记后,那么类关系图中未标记的对象节点也即死亡的对象节点,并将死亡的对象节点确定为目标对象节点,此时将目标对象节点删除,从而释放目标对象节点对应的内存空间。
[0107]
在本技术实施例提供的内存管理方法中,在确定达到内存管理时机时,从标记栈中获取对象节点的对象指针,所述对象指针中包括所述对象节点的深度编码信息;在内存管理的标记阶段,会基于深度编码信息,进行不同的标记处理,其中当所述深度编码信息低于预设的深度阈值时,按照预设的遍历方式标记所述根对象节点的子对象节点直至标记至叶子节点,之后继续对所述标记栈中其他对象节点的子对象进行标记,直至所述标记栈为空,然后在清理阶段基于标记出的对象节点确定未标记的目标对象节点,删除所述目标对象节点,以释放目标对象节点对应的内存空间;如此,对于深度编码信息低于深度阈值的浅遍历对象的子对象节点不再进行入栈出栈的操作而是直接标记,不仅能够减少出栈入栈时间,还能够减少对内存访问以及其入栈所需的栈空间,从而提升内存管理的标记速度,进而提高内存管理效率。
[0108]
在一些实施例中,如图4所示,在步骤s101之前,还可以通过以下步骤在创建对象指针时,增加深度编码信息:
[0109]
步骤s001,获取从堆物理内存中分配出的新建对象的初始对象指针。
[0110]
java虚拟机在执行java程序的过程中会把它所管理的内存划分为若干个不同的数据区域,这些数据区域可以分为两个部分:一部分是线程共享的,一部分则是线程私有的。其中,线程共享的数据区包括方法区和堆,,线程私有的数据区包括虚拟机栈、本地方法栈和程序计数器。
[0111]
堆区中存放的是对象实例,几乎所有的对象实例(和数组)都在堆区分配内存。类的对象从堆物理内存中分配内存空间,也即分配新建对象的初始对象指针。这些对象通过new、newarray、anewarray和multianewarray等指令建立,它们不需要程序代码来显式的释放,因此堆物理内存区为进行内存管理的主要对象。
[0112]
步骤s002,获取所述新建对象的实际深度信息和预设的深度阈值。
[0113]
其中,步骤s002中的“获取所述新建对象的实际深度信息”可以通过以下步骤实现:
[0114]
步骤s0021,获取所述新建对象的类型信息。也即获取新建对象的class信息。
[0115]
步骤s0022,加载所述类型信息,确定所述新建对象的实际深度信息。
[0116]
新建对象的实际深度信息可以在该新建对象的类型信息加载时静态计算好,如在java中可以在类加载时静态计算,即depth(class)函数可在类型加载时一次性计算出来并存储下来供后续调用。其中depth(class)可通过dijkstra算法计算得。在实现时,从当前类开始,遍历其子节点至叶子节点,构建出类引用图,其中每条边的权重设置为-1,从当前类到任何其他叶子节点的最大长度即可转换成最短路径问题,最终取当前类到所有叶子节点类的最大长度的最大值即为当前类的实际深度。
[0117]
在本技术实施例中,深度阈值是利用深度编码信息的所占用的比特位的宽度确定的,例如,深度编码信息占用的比特位为第44和第45个比特位,因此比特位宽度为2,那么深度阈值为2
2-1,也即为3;当比特位宽度为3时,那么深度阈值为2
3-1,也即为7,也就是说,当比特位宽度为d时,深度阈值为2
d-1。
[0118]
步骤s003,基于所述新建对象的实际深度信息和所述深度阈值,确定所述新建对象的编码深度。
[0119]
由于深度阈值是根据比特位宽度确定的,因此,基于比特位宽度d,只能确定出2d种编码深度,也即0到2
d-1,例如比特位宽度为2时,用两个比特位只能表示出00、01、10、11这四种编码深度。
[0120]
因此步骤s003在实现时,当所述实际深度信息小于所述深度阈值时,将所述实际深度信息确定为所述新建对象的编码深度;当所述实际深度信息大于或者等于所述深度阈值时,将所述深度阈值确定为所述新建对象的编码深度。
[0121]
举例来说,如果深度阈值为3,新建对象的实际深度信息为2,那么该新建对象的编码深度为2,如果新建对象的实际深度信息为5,那么该新建对象的编码深度为3。
[0122]
步骤s004,利用所述新建对象的编码深度和所述初始对象指针,确定所述新建对象最终的对象指针。
[0123]
步骤s004在实现时,可以首先确定编码深度的二进制值,然后将该二进制值进行移位操作,并与初始对象指针进行逻辑或操作,从而实现将遍历深度编码至新建对象的对象指针的,从而使得新建对象最终的对象指针中包括深度信息。
[0124]
由于虚拟机运行时通常采用interpreter来解释运行应用的代码,同时采用jit编译器将应用代码编译成二进制代码来加速应用的执行,因此所有对象分配的地方均需要基于上述的步骤s001至步骤s004将新建或者新分配对象的深度信息编码至对象指针中,从而能够在内存管理的标记阶段,通过深度信息确定是否为浅遍历对象,并对浅遍历对象的子对象节点直接按照一定的遍历方式进行标记,而不用再进行入栈、出栈操作,不仅能够提高内存管理效率还能够降低对栈空间的占用。
[0125]
在一些实施例中,上述步骤s004“利用所述新建对象的深度编码信息和所述初始对象指针,确定所述新建对象最终的对象指针”,可以通过以下步骤实现:
[0126]
步骤s0041,获取预设的深度编码信息的起始位数。
[0127]
其中,起始位数大于所述初始对象指针的总位数,例如初始对象指针为0xabcd0000,也即总位数为32位,那么该起始位数要大于32,也就是说深度编码信息占用的是初始对象指针没有占用的高bite位。例如起始位数可以是44,可以是35、48等。
[0128]
步骤s0042,将所述编码深度的二进制值按照所述起始位数进行左向移位操作,得到移位深度信息。
[0129]
步骤s0042在实现时,也即将编码深度的二进制值,向左移该起始位数个比特位,得到移位深度信息。例如编码深度为2,编码深度的二进制为10,起始位数为44,那么将二进制数10,向左移44位,得到移位深度信息0x100000000000。
[0130]
步骤s0043,将所述移位深度信息和初始对象指针进行逻辑或操作,得到所述新建对象最终的对象指针。
[0131]
假设初始对象指针为0xabcd0000,移位深度信息为0x100000000000,将移位深度信息和初始对象指针进行逻辑或操作,得到新建对象最终的对象指针0x1000abcd0000。
[0132]
在将新建对象的深度信息编码至对象指针中时,如果在对象指针未使用的低位上编码深度信息,则后续所有指针的使用,均需要额外的操作把编码信息去除,影响性能,因此在步骤s0041至步骤s0043中,在对象指针高位进行深度信息编码,从而得到新建对象最终的对象指针,在后续标记过程中可以通过以下步骤得到对象节点的编码深度:
[0133]
步骤s005,将所述对象节点的对象指针按照所述起始位数进行右向移位操作,得到所述对象节点的深度编码信息。
[0134]
承接上述的距离,对象节点的对象指针为0x1000abcd0000,起始位数为44,步骤s005在实现时,也即将0x1000abcd0000右移44位,得到该对象节点的深度编码信息0x000000000001。
[0135]
步骤s006,将所述深度编码信息的十进制值确定为所述对象节点的编码深度。
[0136]
该深度编码信息的十进制值也即为2,因此得到该对象节点的编码深度为2。
[0137]
通过上述的步骤s005至步骤s006可以看出,在对象指针高位进行深度信息编码,从而得到新建对象最终的对象指针,在后续标记过程中,只需要将对象指针进行移位操作,即可确定为深度编码信息,并确定出编码深度,移位操作相对于内存读取操作的开销近乎为零,从而实现更低成本的浅遍历对象的识别,进而提高内存管理效率。
[0138]
并且在对象指针高位进行深度信息编码,从而得到新建对象最终的对象指针,那么基于最终的对象指针可以有效的和堆多重映射(heap multi-mapping)结合起来,将堆物理内存映射到不同的虚拟内存中:
[0139]
步骤s201,获取所述堆物理内存的内存信息。
[0140]
这里,堆物理内存的内存信息至少包括堆物理内存的存储空间大小,例如可以是16g、32g等等,在一些实施例中,该堆物理内存的内存信息还可以包括该堆物理内存的起始地址,结束地址等等。
[0141]
步骤s202,基于多重映射技术、所述内存信息和所述起始位数,将所述堆物理内存映射到不同深度编码信息对应的虚拟内存中。
[0142]
在实现时,可以基于起始位数和深度编码信息确定出不同各个虚拟内存的起始地址,并且不同深度编码信息对应的虚拟内存占用的空间大小即为堆物理内存的占用空间大小。
[0143]
如此,将堆采用multi-mapping技术映射到不同遍历深度编码对应的虚拟内存地址中,不同类型的对象指针指向的是同一个堆,从而能够保证不同编码的对象指针在程序运行时能够正确工作。
[0144]
基于前述的实施例,本技术实施例再提供一种内存管理方法,应用于服务器,图5为本技术实施例提供的内存管理方法的再一种实现流程示意图,如图5所示,该流程包括:
[0145]
步骤s301,获取从堆物理内存中分配出的新建对象的初始对象指针。
[0146]
步骤s302,获取所述新建对象的实际深度信息和预设的深度阈值。
[0147]
步骤s303,基于所述新建对象的实际深度信息和所述深度阈值,确定所述新建对象的编码深度。
[0148]
步骤s304,利用所述新建对象的编码深度和所述初始对象指针,确定所述新建对象最终的对象指针。
[0149]
步骤s305,在达到内存管理时机时,获取根对象节点集合。
[0150]
其中,根对象节点为确定存活的对象。
[0151]
步骤s306,将根对象节点集合中的各个根对象节点的对象指针进行标记,并加入到标记栈中。
[0152]
也就是说,标记栈中存储的是存活对象的对象指针。
[0153]
步骤s307,从标记栈中获取对象节点的对象指针。
[0154]
步骤s307在实现时,可以是将标记栈中栈顶的对象指针进行出栈,该所述对象指
针中包括所述对象节点的深度编码信息。
[0155]
步骤s308,判断基于该对象节点的深度编码信息确定的编码深度是否低于预设的深度阈值。
[0156]
其中,当所述编码深度低于预设的深度阈值时,说明该对象节点的实际深度较小,可以认为是浅遍历对象,此时进入步骤s309;当编码深度不低于深度阈值时,说明给对象节点不为浅遍历对象,此时进入步骤s315。
[0157]
步骤s309,确定该对象节点是否为叶子节点。
[0158]
确定对象节点是否为叶子节点,在实现时可以是确定该对象节点的编码深度是否为0,如果该对象节点的编码深度不为0,说明该对象节点不为叶子节点,也即该对象节点有子节点,此时进入步骤s310;如果该对象节点的编码深度为0,说明该对象节点为叶子节点,也即该对象节点没有子对象节点,此时跳出该对象节点的标记流程,进入步骤s318。
[0159]
步骤s310,获取并标记所述对象节点的子对象节点。
[0160]
步骤s311,获取所述子对象节点的编码深度。
[0161]
步骤s312,判断子对象节点的编码深度是否小于所述对象节点的遍历深度。
[0162]
其中,当子对象节点的编码深度小于该对象节点的遍历深度时,说明该子对象节点也为浅遍历节点,此时进入步骤s313;当子对象节点的编码深度大于或者等于该深度阈值时,说明静态计算的实际深度信息和运行时不匹配,此时进入步骤s314。
[0163]
步骤s313,按照所述预设遍历方式标记所述子对象节点的子对象节点直至标记至叶子节点。
[0164]
该步骤的实现方式与前述实施例的步骤s102的实现方式是类似的,也即先标记该子对象节点的子对象节点,然后判断该子对象节点的子对象节点是否为叶子节点,当该子对象节点的子对象节点为叶子节点时,跳出该子对象节点的标记流程,继续标记下一个子对象节点;如果该子对象节点的子对象节点不为叶子节点时,按照预设的遍历方式标记该子对象节点的子对象节点的子对象节点,直至标记至叶子节点。其中预设的遍历方式可以是深度优先遍历方式、宽度优先遍历方式等。
[0165]
在步骤s313之后,则进入步骤s318。
[0166]
步骤s314,将标记后的所述子对象节点增加至所述标记栈。
[0167]
由于通常在大多数的编程语言中存在类继承关系,允许某个类的一个字段field存放字段对应类的子对象,使得静态计算的遍历深度和运行时不匹配,如果静态计算的实际深度信息和运行时不匹配时,那么将该子对象作为非浅遍历进行处理,此时将标记后的对象节点增加至标记栈。并在步骤s314之后,则进入步骤s318,继续对标记栈中的其他对象节点的子对象节点进行标记。
[0168]
步骤s315,获取所述对象节点的子对象节点。
[0169]
当基于对象节点的深度编码信息确定该对象节点的遍历深度不小于深度阈值时,说明该对象节点不为浅遍历对象,那么此时仅仅标记该对象节点的子对象节点。
[0170]
步骤s316,如果所述子对象节点未被标记,标记所述子对象节点。
[0171]
由于该对象节点的子对象节点可能是其他对象节点的子对象节点,已经在标记其他对象节点的子对象节点进行标记,因此,在该步骤中仅仅标记未标记的子对象节点。
[0172]
步骤s317,将标记后的所述子对象节点增加至所述标记栈。
[0173]
步骤s318,基于所述标记栈中其他对象节点的深度编码信息对所述其他对象节点的子对象进行标记,直至所述标记栈为空。
[0174]
如果上述取出的对象节点为叶子节点,或者对上述出栈的对象节点的子对象节点都标记完成后,那么继续从标记栈中出栈一个对象节点,并进行标记过程,直至标记栈为空,此时也就完成了对整个类关系图中存活对象的标记。
[0175]
步骤s319,基于标记出的对象节点确定未标记的目标对象节点,删除所述目标对象节点,以释放目标对象节点对应的内存空间。
[0176]
在本技术实施例提供的内存管理方法中,在从堆物理内存中为新建对象节点创建初始对象指针后,要通过加载新建对象的class信息确定新建对象的实际深度信息,并基于深度阈值确定编码深度,将编码深度编码至对象指针未使用的高位比特位,得到最终的具有深度编码信息的对象指针,在内存管理的标记阶段,会通过对对象指针的移位操作获取对象节点的遍历深度,并且在基于该编码深度确定该对象节点不为浅遍历对象时,那么标记该对象节点的子对象节点,并将标记后的子对象节点进行入栈,当该对象节点为浅遍历对象时,不再将该对象节点的子对象节点进行再次的标记入栈、出栈过程,而是通过预设的遍历方式直接将该对象节点的子对象节点进行标记,如此不仅能够减少对标记栈的空间占用,并且能够减少浅遍历对象节点的子对象节点的类字段的内存访问,从而降低标记阶段耗费的时间,提升内存管理效率。
[0177]
下面,将说明本技术实施例在一个实际的应用场景中的示例性应用。
[0178]
本技术实施例提供一种内存管理方法,在对象分配时,使用对象指针的高位未使用的bit存储该对象的遍历深度,然后在gc marking阶段,利用对象指针中存储的遍历深度进行浅遍历对象的识别,从而提高内存管理效率。
[0179]
本技术实施例提供的内存管理方法可应用于所有基于追踪(tracing)的语言虚拟机运行时的内存管理模块中,用来减少gc mark阶段的cpu和内存消耗,属于底层软件优化,具有天然的普适性。对浅遍历对象越多的应用其提升的效果越好,特别在大内存的堆下,由于需要处理的对象个数以十亿为基本单位,此时对于gc的mark时间提升效果越好。
[0180]
当前主要用于大数据领域,如各类java大数据应用hadoop、hbase、zoo keeper等,此类应用通常使用的堆较大,会缓存很多的数据信息,如zookeepe r中通常会缓存大量的配置型信息,这些配置信息通常以字符串(string)的形式存在。而java语言中string对象仅包含一个byte[]对象,如果gc需要遍历string对象开始的对象树,只需要向下遍历一层就可以到达叶子节点byte[]对象,因此string为浅遍历对象。由此可见,在gc的marking阶段,如果对像string这样的浅遍历对象直接进行dfs遍历标记的话,可以减少string本身和孩子节点byte[]数组的出栈和入栈,从而极大的降低gc的mark时间和mark stack的内存消耗。
[0181]
使用颜色指针在对象分配时返回的对象指针高位编码当前对象的遍历深度,并在gc mark阶段时直接使用mark stack中取出的对象指针进行遍历深度的移位解码,就能以近乎零开销的方式区分出浅遍历对象,从而加速浅遍历对象的处理,减少浅遍历对象的出栈和入栈时间、内存访问,以及其入栈所需的mark stack空间,提升gc的mark阶段效率。
[0182]
以下对本技术实施例提供的内存管理方法的实现过程进行说明。
[0183]
本技术实施例提供的内存管理方法在实现时可以通过以下三个步骤实现:
[0184]
步骤s601,颜色指针编码设计。
[0185]
在本技术实施例中,为有效的传递浅遍历对象的遍历深度信息,采用对象指针高位中部分未使用的bit来编码对象的深度信息。在对象指针高位进行信息编码,可以有效的和堆多重映射(heap multi-mapping)结合起来,保证不同颜色编码的指针指向同一个堆,并可以不经解码照常使用。而在对象指针低位未使用的bit数量有限(64bit系统下,最低3位未使用),如果在低位上编码颜色信息,则后续所有指针的使用,均需要额外的操作把编码信息去除,影响性能。
[0186]
如图6a所示,对64位的对象指针,可选择第k个bit开始共d个bit作为对象的遍历深度的编码字段501,可编码2d种深度信息,即遍历深度信息对应于2d种颜色。
[0187]
举例来说,当选择的宽度为2时,即d=2,如图6b所示可将对象分为四类,即三类浅遍历对象和一类普通对象:
[0188]
遍历深度为0的浅遍历对象611,其遍历深度的二进制编码为bits
k,d=2
=00,带有该类编码的对象指针为叶子节点指针,即不包含任何孩子节点,如各类原始数组对象(byte[]、short[]、int[])等;
[0189]
遍历深度为1的浅遍历对象612,其遍历深度的二进制编码为bits
k,d=2
=01,遍历该类对象指针时需要向下遍历一层可到达叶子节点,如java中常见的string对象等;
[0190]
遍历深度为2的浅遍历对象613,其遍历深度的二进制编码为bits
k,d=2
=10,在遍历该对象时需要向下遍历两层才可达叶子节点,如string[]对象等;
[0191]
普通对象614,其遍历深度的二进制编码为bits
k,d=2
=11,普通对象可能包含任何深度的孩子节点对象,gc marking中不需要像前面三类浅遍历对象一样特殊处理。
[0192]
当选择k=44和d=2时,对于刚从堆中分配出来的对象指针0xabcd0000,可根据其对象的类信息中包含的类指向图来给该指针编码不同的遍历深度,如图7所示,如果属于遍历深度为0的浅遍历对象则最终的对象指针为0xabcd0000,如果为遍历深度为1的浅遍历对象则最终的对象指针为0x1000abcd0000,如果为遍历深度为2的浅遍历对象则最终的对象指针为0x2000abcd0000,如果为普通对象则最终的对象指针为0x3000abcd0000。为了保证不同编码的对象指针在程序运行时能够正确工作,即不同类型的对象指针看到的是同一个堆,需要将堆采用multi-mapping技术映射到不同遍历深度编码对应的虚拟内存地址中。图7中指针所在的堆,需要将其堆对应的物理内存同时影射到虚拟地址在0x0、0x100000000000、0x200000000000、0x300000000000对应的某个偏移上。
[0193]
步骤s602,对象指针中颜色信息的生成。
[0194]
为提供遍历深度信息给gc的mark阶段,在步骤s601中,对象分配时就将遍历深度作为颜色编入对象指针中。虚拟机运行时通常采用interpreter来解释运行应用的代码,同时采用jit编译器将应用代码编译成二进制代码来加速应用的执行,因此所有对象分配的地方均需要进行以下逻辑修改:
[0195]
一、在interpreter中调用对象分配时,需要将遍历深度信息编码入分配的对象指针中。
[0196]
二、jit编译器则需要在对象分配的代码生成中,添加编码颜色信息的逻辑,以使得最终分配的对象指针包含遍历深度信息。
[0197]
图8中给出了运行时(runtime)在对象分配时添加遍历深度的逻辑,如图8所示包
括以下步骤:
[0198]
步骤s801,创建一个对象obj。
[0199]
步骤s802,判断对象是否为浅遍历对象,即判断其类型(class)到达任意叶子节点类型(leaf child class)的深度是否小于最大的编码长度(2
d-1)。
[0200]
如果该对象的类型到达所有叶子节点类型(leaf child class)的深度小于最大的编码长度(2
d-1),说明该对象为浅遍历对象,此时进入步骤s803;如果到达任意叶子节点类型(leaf child class)的深度大于或者等于最大的编码长度(2
d-1),确定该对象不为浅遍历对象,此时进入步骤s804。
[0201]
步骤s803,确定遍历深度信息为depth(class)。
[0202]
步骤s804,确定遍历深度信息为2
d-1。
[0203]
步骤s805,根据其浅遍历对象信息将不同的遍历深度编码进最终的对象指针中。
[0204]
对象的遍历深度信息,可以在对象的类型信息加载时静态计算好,如在java中可以在类加载时静态计算,即depth(class)函数可在类型加载时一次性计算出来并存储下来供后续调用。其中depth(class)可通过dijkstra算法计算得出,如图8中右边的标记框811所示,从当前类开始,遍历其子节点至叶子节点,构建出类引用图,其中每条边的权重设置为-1,从当前类到任何其他叶子节点的最大长度即可转换成shortest path problem[1],最终取当前类到所有叶子节点类的最大长度的最大值即为当前类的遍历深度。
[0205]
由于通常在大多数的编程语言中存在类继承关系,允许某个类的一个字段field存放字段对应类的子对象,使得静态计算的遍历深度和运行时不匹配,但是由于所有的对象指针均带有遍历深度信息,使得运行时可以轻易识别出这些遍历深度处理动态不匹配的情况,如遇到不匹配的对象指针,退回到默认处理等。
[0206]
步骤s603,gc标记阶段对颜色指针的处理。
[0207]
基于tracing的内存管理gc模块,通常需要一个标记mark阶段,来标记所有活着的对象,然后将剩余的未标记的死对象在后续阶段清理掉。gc的mark阶段通常从一组根对象节点集合(如线程栈上的对象指针等)出发,递归标记整个活着的对象图,从而把活对象图中的每个对象都标记上,如图9所示给出了“先标记再入栈”的标记过程,其他mark方式如“先入栈后标记”的标记过程仅流程图中“标记对象”这一函数方法调用的位置不同。
[0208]
图9为本技术实施例提供的gc标记阶段处理颜色指针的实现流程示意图,如图9所示,该流程包括:
[0209]
步骤s901,判断mark stack是否为空。
[0210]
当mark stack不为空时,进入步骤s902,如果mark stack为空时,进入步骤s906。
[0211]
步骤s902,pop出一个对象指针。
[0212]
步骤s903,检查对象指针是否为浅遍历对象。
[0213]
在实现时,通过移位操作得到对象的遍历深度,根据该深度来检查对象是否为浅遍历对象。如果depth
obj
小于2
d-1,那么对象指针为浅遍历对象,进入步骤s904;如果对象指针不为浅遍历对象,进入步骤s905。
[0214]
步骤s904,通过dfs方式标记该对象所有的子对象至叶子节点。
[0215]
图9左侧标记框911为步骤s904的实现代码,通过该代码可以看出,步骤s904在实现时包括以下步骤:
[0216]
步骤s9041,如果遍历到叶子节点,则直接返回。
[0217]
步骤s9042,对该对象所有的孩子节点对象进行遍历处理,首先进行子节点的标记,如果已经标记则继续下一个子节点。
[0218]
步骤s9043,如果步骤s9042中的子节点的遍历深度小于depthobj,即该节点在需要递归标记的路径上,则继续dfs扫描该子节点。
[0219]
步骤s9044,如果步骤s9042中的子节点的遍历深度不小于depthobj,则该节点为动态生成的子类节点,属于前一小节中静态分析遍历深度中的例外情况,需要将该节点指针放入mark stack中,待后续处理。
[0220]
步骤s905,标记该对象的所有子对象。
[0221]
如果depth
obj
等于2
d-1,则走传统marking流程,即标记该对象的子对象,如果未标记则把该对象放入mark stack中。
[0222]
在本技术实施例提供的内存管理方法中,使用颜色指针在对象分配时返回的对象指针高位编码当前对象的遍历深度,并在gc mark阶段时直接使用mark stack中取出的对象指针进行遍历深度的移位解码,就能以近乎零开销的方式区分出浅遍历对象,从而减少gc mark阶段的任务量,加速浅遍历对象的处理,减少浅遍历对象的出栈和入栈时间、内存访问,以及其入栈所需的mark stack空间,提升gc的mark阶段效率。
[0223]
下面继续说明本技术实施例提供的内存管理装置443的实施为软件模块的示例性结构,在一些实施例中,如图2所示,存储在存储器440的内存管理装置443中的软件模块可以包括:
[0224]
第一获取模块4431,用于在确定达到内存管理时机时,从标记栈中获取对象节点的对象指针,所述对象指针中包括所述对象节点的深度编码信息;
[0225]
第一标记模块4432,用于当基于所述深度编码信息确定所述对象节点的编码深度低于预设的深度阈值时,按照预设的遍历方式标记所述根对象节点的子对象节点直至标记至叶子节点;
[0226]
第二标记模块4433,用于基于所述标记栈中其他对象节点的深度编码信息对所述其他对象节点的子对象进行标记,直至所述标记栈为空;
[0227]
清除模块4434,用于基于标记出的对象节点确定未标记的目标对象节点,删除所述目标对象节点,以释放目标对象节点对应的内存空间。
[0228]
在一些实施例中,该装置还包括:
[0229]
第二获取模块,用于获取从堆物理内存中分配出的新建对象的初始对象指针;
[0230]
第三获取模块,用于获取所述新建对象的实际深度信息和预设的深度阈值;
[0231]
第一确定模块,用于基于所述新建对象的实际深度信息和所述深度阈值,确定所述新建对象的编码深度;
[0232]
第二确定模块,用于利用所述新建对象的编码深度和所述初始对象指针,确定所述新建对象最终的对象指针。
[0233]
在一些实施例中,该第三获取模块,还用于:
[0234]
获取所述新建对象的类型信息;
[0235]
加载所述类型信息,确定所述新建对象的实际深度信息。
[0236]
在一些实施例中,该第一确定模块,还用于:
[0237]
当所述实际深度信息小于所述深度阈值时,将所述实际深度信息确定为所述新建对象的编码深度;
[0238]
当所述实际深度信息大于或者等于所述深度阈值时,将所述深度阈值确定为所述新建对象的编码深度。
[0239]
在一些实施例中,该第二确定模块,还用于:
[0240]
获取预设的深度编码信息的起始位数,所述起始位数大于所述初始对象指针的总位数;
[0241]
将所述编码深度的二进制值确定为所述对象节点的深度编码信息;
[0242]
将所述深度编码信息按照所述起始位数进行左向移位操作,得到移位深度信息;
[0243]
将所述移位深度信息和初始对象指针进行逻辑或操作,得到所述新建对象最终的对象指针。
[0244]
在一些实施例中,该装置还包括:
[0245]
移位模块,用于将所述对象节点的对象指针按照所述起始位数进行右向移位操作,得到所述深度编码信息;
[0246]
第三确定模块,用于将所述深度编码信息的十进制值确定为所述对象节点的编码深度。
[0247]
在一些实施例中,该第一标记模块,还用于:
[0248]
当基于所述深度编码信息确定所述对象节点的编码深度低于预设的深度阈值时,确定该对象节点是否为叶子节点;
[0249]
当所述对象节点不为叶子节点时,获取并标记所述对象节点的子对象节点;
[0250]
获取所述子对象节点的编码深度;
[0251]
当所述子对象节点的编码深度小于所述对象节点的编码深度时,按照所述预设遍历方式标记所述子对象节点的子对象节点直至标记至叶子节点。
[0252]
在一些实施例中,该装置还包括:
[0253]
第一入栈模块,用于当所述子对象节点的编码深度大于或者等于所述对象节点的编码深度时,将标记后的所述子对象节点增加至所述标记栈。
[0254]
在一些实施例中,该装置还包括:
[0255]
第四获取模块,用于当基于所述深度编码信息确定所述对象节点的编码深度不低于预设的深度阈值时,获取所述对象节点的子对象节点;
[0256]
第三标记模块,用于如果所述子对象节点未被标记,标记所述子对象子节点;
[0257]
第二入栈模块,用于将标记后的所述子对象节点增加至所述标记栈。
[0258]
在一些实施例中,该装置还包括:
[0259]
第五获取模块,用于获取所述堆物理内存的内存信息;
[0260]
映射模块,用于基于多重映射技术、所述内存信息和所述起始位数,将所述堆物理内存映射到不同深度编码信息对应的虚拟内存中。
[0261]
需要说明的是,以上内存管理装置实施例项的描述,与上述方法描述是类似的,具有同方法实施例相同的有益效果。对于本技术内存管理装置实施例中未披露的技术细节,本领域的技术人员请参照本技术方法实施例的描述而理解。
[0262]
本技术实施例提供了一种计算机程序产品或计算机程序,该计算机程序产品或计
算机程序包括计算机指令,该计算机指令存储在计算机可读存储介质中。计算机设备的处理器从计算机可读存储介质读取该计算机指令,处理器执行该计算机指令,使得该计算机设备执行本技术实施例上述的内存管理方法。
[0263]
本技术实施例提供一种存储有可执行指令的计算机可读存储介质,其中存储有可执行指令,当可执行指令被处理器执行时,将引起处理器执行本技术实施例提供的方法,例如,如图3、图4、图5示出的方法。
[0264]
在一些实施例中,计算机可读存储介质可以是fram、rom、prom、eprom、eeprom、闪存、磁表面存储器、光盘、或cd-rom等存储器;也可以是包括上述存储器之一或任意组合的各种设备。
[0265]
在一些实施例中,可执行指令可以采用程序、软件、软件模块、脚本或代码的形式,按任意形式的编程语言(包括编译或解释语言,或者声明性或过程性语言)来编写,并且其可按任意形式部署,包括被部署为独立的程序或者被部署为模块、组件、子例程或者适合在计算环境中使用的其它单元。
[0266]
作为示例,可执行指令可以但不一定对应于文件系统中的文件,可以可被存储在保存其它程序或数据的文件的一部分,例如,存储在超文本标记语言(html,hyper text markup language)文档中的一个或多个脚本中,存储在专用于所讨论的程序的单个文件中,或者,存储在多个协同文件(例如,存储一个或多个模块、子程序或代码部分的文件)中。
[0267]
作为示例,可执行指令可被部署为在一个计算设备上执行,或者在位于一个地点的多个计算设备上执行,又或者,在分布在多个地点且通过通信网络互连的多个计算设备上执行。
[0268]
以上所述,仅为本技术的实施例而已,并非用于限定本技术的保护范围。凡在本技术的精神和范围之内所作的任何修改、等同替换和改进等,均包含在本技术的保护范围之内。
再多了解一些

本文用于创业者技术爱好者查询,仅供学习研究,如用于商业用途,请联系技术所有人。

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

相关文献