CN113515376A - 一种内存管理方法、装置、电子设备及存储介质 - Google Patents
一种内存管理方法、装置、电子设备及存储介质 Download PDFInfo
- Publication number
- CN113515376A CN113515376A CN202110562803.6A CN202110562803A CN113515376A CN 113515376 A CN113515376 A CN 113515376A CN 202110562803 A CN202110562803 A CN 202110562803A CN 113515376 A CN113515376 A CN 113515376A
- Authority
- CN
- China
- Prior art keywords
- memory
- slab
- slice
- localcache
- idle
- Prior art date
- Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
- Pending
Links
Images
Classifications
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F9/00—Arrangements for program control, e.g. control units
- G06F9/06—Arrangements for program control, e.g. control units using stored programs, i.e. using an internal store of processing equipment to receive or retain programs
- G06F9/46—Multiprogramming arrangements
- G06F9/50—Allocation of resources, e.g. of the central processing unit [CPU]
- G06F9/5005—Allocation of resources, e.g. of the central processing unit [CPU] to service a request
- G06F9/5011—Allocation of resources, e.g. of the central processing unit [CPU] to service a request the resources being hardware resources other than CPUs, Servers and Terminals
- G06F9/5016—Allocation of resources, e.g. of the central processing unit [CPU] to service a request the resources being hardware resources other than CPUs, Servers and Terminals the resource being the memory
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F9/00—Arrangements for program control, e.g. control units
- G06F9/06—Arrangements for program control, e.g. control units using stored programs, i.e. using an internal store of processing equipment to receive or retain programs
- G06F9/46—Multiprogramming arrangements
- G06F9/50—Allocation of resources, e.g. of the central processing unit [CPU]
- G06F9/5005—Allocation of resources, e.g. of the central processing unit [CPU] to service a request
- G06F9/5011—Allocation of resources, e.g. of the central processing unit [CPU] to service a request the resources being hardware resources other than CPUs, Servers and Terminals
- G06F9/5022—Mechanisms to release resources
Landscapes
- Engineering & Computer Science (AREA)
- Software Systems (AREA)
- Theoretical Computer Science (AREA)
- Physics & Mathematics (AREA)
- General Engineering & Computer Science (AREA)
- General Physics & Mathematics (AREA)
- Memory System (AREA)
Abstract
本公开提供了一种内存管理方法、装置、电子设备及存储介质,用于解决内存利用率低、内存分配冲突的技术问题。本公开通过对内存进行分类分级管理,使业务实例所申请的内存空间尽可能地适配所提供的不同尺寸类型的内存块,通过将不同块分类及将不同大小的内存块分类组成组,将组与业务实例绑定,针对不同实例实现内存管理上的隔离,从而提高了内存使用率,避免了不同实例在内存分配上可能产生的冲突。
Description
技术领域
本公开涉及计算及存储技术领域,尤其涉及一种内存管理方法、装置、电子设备及存储介质。
背景技术
云计算、物联网、社交网络等新兴服务的兴起促使人类社会的数据种类和规模正以前所未有的速度增长,大数据时代正式到来。大数据的规模效应给数据存储带来了极大的挑战。以Ceph为代表的分布式存储系统被广泛的应用于各种存储产品。在一个存储集群中各个实例(如OSD,MDS)对业务的高效处理能力决定了存储集群的性能,而各个实例在处理业务过程中对于内存的申请和释放效率是影响实例性能的关键因素之一。
基于Ceph的存储集群中的实例通过tcmalloc或者jemalloc等动态连接库中的接口实现内存分配和释放。tcmaloc和jemalloc的关键设计思想是将内存分配分为几类,如小对象,中对象,大对象。对于每种分类,细分若干个级别,减少内存碎片。对于线程保存其缓存,在应用进行内存申请释放时优先和缓存交互,提高效率。
tcmalloc和jemalloc作为通用的内存管理器在设计上考虑的是更通用的场景,采用的是预先设置固定内存大小级别的方式,没有针对具体的实际业务场景进行优化,如果实际业务频繁申请的内存空间的尺寸大小不在预先设置的内存级别划分之中,随着业务的进行会产生大量的内存碎片,造成内存浪费。
发明内容
有鉴于此,本公开提供一种内存管理方法、装置、电子设备及存储介质,用于解决内存利用率低、内存分配冲突的技术问题。
图1为本公开提供的内存管理方法的步骤流程图,该方法用于实现实例的内存分配,该方法包括:
步骤101.基于实例所申请的内存空间的大小适配块管理对象Part分类;其中,Part为由多个具有相同尺寸的切片管理内存块Slab组成的内存管理对象;所述Slab中包括由原始内存块Blk切分的多个相同大小的内存片Slice;所述Part依据Slice的大小分类;
步骤102.从本地缓存LocalCache中包括的与适配的Part分类一致的空闲内存片Slice中为实例分配内存;
步骤103.当所述LocalCache中的空间不足时,从适配的Part分类对应的Part所管理的具有空闲Slice的Slab中为实例分配内存;
步骤104.当适配的Part中无空闲的Slice时,从内存池MemPool中获取原始内存块Blk,将Blk初始化为适配的Part分类对应的Slab,将Slab加入到适配的Part中,再从适配的Part中为实例分配内存。
基于本公开实施例,进一步地,所述Part包括:
无空闲链表Emptylist,其中的所有Slab都是已将内部内存片Slice全部分配出去的Slab;
部分空闲链表Partiallist,其中的所有Slab都是已将内部部分内存片Slice分配出去,还有部分Slice未被分配出去的Slab;
全空闲链表Fulllist,其中的所有Slab都是全部内存片Slice都未被分配的Slab;
所述从适配的Part分类对应的Part所管理的具有空闲Slice的Slab中为实例分配内存的方法为:
首先判断Partiallist中是否有充足的空闲的Slice可供分配,如果有则从对应的Slab中分配,如果没有则从Fulllist中获取未被分配的Slab填充到Partiallist中,然后再从填充的Slab中分配。
基于本公开实施例,进一步地,所述方法还用于实现实例的内存释放,内存释放的步骤包括:
在将释放的内存释放回LocalCache不会导致LocalCache溢出的情况下,将释放的内存释放回LocalCache;
在释放回LocalCache会导致LocalCache溢出的情况下,将释放的内存释放回Part;
在释放回Part会导致Part溢出的情况下,将释放的内存释放回MemPool;
在释放回MemPool会导致MemPool溢出的情况下,将释放的内存释放回操作系统。
基于本公开实施例,进一步地,所述方法还包括:
所述实例与块管理对象组Group绑定,所述Group由多个不同分类的Part组成;
所述基于所申请的内存空间的大小适配块管理对象Part分类具体为:在所述Group所包含的Part分类中进行适配;
所述适配的Part为所述Group中的Part。
基于本公开实施例,进一步地,所述方法中:
在实例启动时,使用Part分类表对所述Group进行初始化;
所述Part分类表采用默认配置和/或采用如下动态配置方法:
对实例申请的不同大小的内存空间的频率进行统计分析;
基于预设门限,在默认Part分类表中新增频率高于预设门限的内存空间大小对应的Part分类。
图2为本公开一实施例提供的一种内存管理装置结构示意图,该装置200中的各功能模块可以采用软件、硬件或软硬件相结合的方式实现。所述装置200用于实现实例的内存分配,该装置包括:
适配模块210,用于基于所申请的内存空间的大小适配块管理对象Part分类;其中,Part为由多个具有相同尺寸的切片管理内存块Slab组成的内存管理对象;所述Slab中包括由原始内存块Blk切分的多个相同大小的内存片Slice;所述Part依据Slice的大小分类;
本地缓存分配模块211,用于从本地缓存LocalCache中包括的与适配的Part分类一致的空闲内存片Slice中为实例分配内存;
块管理对象分配模块212,用于当所述LocalCache中的空间不足时,从适配的Part分类对应的Part所管理的具有空闲Slice的Slab中为实例分配内存;
内存池分配模块213,用于在适配的Part中无空闲的Slice时,从内存池MemPool中获取原始内存块Blk,将Blk初始化为适配的Part分类对应的Slab,将Slab加入到适配的Part中,再从适配的Part中为实例分配内存。
基于本公开实施例,进一步地,所述块管理对象分配模块212中包括:
无空闲链表Emptylist,其中的所有Slab都是已将内部内存片Slice全部分配出去的Slab;
部分空闲链表Partiallist,其中的所有Slab都是已将内部部分内存片Slice分配出去,还有部分Slice未被分配出去的Slab;
全空闲链表Fulllist,其中的所有Slab都是全部内存片Slice都未被分配的Slab;
所述块管理对象分配模块从适配的Part分类对应的Part所管理的具有空闲Slice的Slab中为实例分配内存的方法为:
首先判断Partiallist中是否有充足的空闲的Slice可供分配,如果有则从对应的Slab中分配,如果没有则从Fulllist中获取未被分配的Slab填充到Partiallist中,然后再从填充的Slab中分配。
基于本公开实施例,进一步地,所述装置200还用于实现实例的内存释放,该装置200还包括:
第一释放模块,用于在将释放的内存释放回LocalCache不会导致LocalCache溢出的情况下,将释放的内存释放回LocalCache;
第二释放模块,用于在释放回LocalCache会导致LocalCache溢出的情况下,将释放的内存释放回Part;
第三释放模块,用于在释放回Part会导致Part溢出的情况下,将释放的内存释放回MemPool;
第四释放模块,用于在释放回MemPool会导致MemPool溢出的情况下,将释放的内存释放回操作系统。
基于本公开实施例,进一步地,所述实例与块管理对象组Group绑定,所述Group由多个不同分类的Part组成;
所述适配模块210在所述Group所包含的Part分类中进行Part分类的适配,所述适配的Part为所述Group中的Part。
基于本公开实施例,进一步地,所述装置200还包括:
初始化模块,用于在实例启动时,使用Part分类表对所述Group进行初始化;所述Part分类表采用默认配置和/或采用动态配置;
动态配置模块,用于在Part分类表采用动态配置的情况下,对实例申请的不同大小的内存空间的频率进行统计分析;以及基于预设门限,在默认Part分类表中新增频率高于预设门限的内存空间大小对应的Part分类。
本公开提供的内存管理方法通过对内存进行分类分级管理,使业务实例所申请的内存空间尽可能地适配所提供的不同尺寸类型的内存块,通过将不同块分类及将不同大小的内存块分类组成组,将组与业务实例绑定,针对不同实例实现内存管理上的隔离,从而提高了内存使用率,避免了不同实例在内存分配上可能产生的冲突。
附图说明
为了更加清楚地说明本公开实施例或者现有技术中的技术方案,下面将对本公开实施例或者现有技术描述中所需要使用的附图作简单地介绍,显而易见地,下面描述中的附图仅仅是本公开中记载的一些实施例,对于本领域普通技术人员来讲,还可以根据本公开实施例的这些附图获得其他的附图。
图1为本公开提供的内存管理方法的步骤流程图;
图2为本公开提供的一种内存管理装置结构示意图;
图3为tcmalloc和jemalloc进行内存分配和释放时所采用的内存分层结构示意图;
图4为本公开一实施例提供的内存管理方法所采用的内存组织结构示意图;
图5为本公开一实施例提供的对Part分类配置进行动态调整的方法步骤示意图;
图6为本公开一实施例提供的内存管理方法中内存申请的步骤流程图;
图7为本公开一实施例提供的内存管理方法中内存释放的步骤流程图;
图8为本公开一实施例提供的一种电子设备结构示意图。
具体实施方式
在本公开实施例使用的术语仅仅是出于描述特定实施例的目的,而非限制本公开实施例。本公开实施例中所使用的单数形式的“一种”、“所述”和“该”也旨在包括多数形式,除非上下文清楚地表示其它含义。本公开中使用的术语“和/或”是指包含一个或多个相关联的列出项目的任何或所有可能组合。
应当理解,尽管在本公开实施例可能采用术语第一、第二、第三等来描述各种信息,但这些信息不应限于这些术语。这些术语仅用来将同一类型的信息彼此区分开。例如,在不脱离本公开实施例范围的情况下,第一信息也可以被称为第二信息,类似地,第二信息也可以被称为第一信息。取决于语境,此外,所使用的词语“如果”可以被解释成为“在……时”或“当……时”或“响应于确定”。
Ceph存储集群中的实例通过tcmalloc或者jemalloc等动态连接库提供的接口实现内存分配和释放。发明人基于对tcmaloc和jemalloc的内存分配和回收方式的分析发现,tcmaloc和jemalloc将分配的内存分为几类,如小对象,中对象,大对象,对于每种分类,又细分若干个级别。对于线程保存其缓存,在应用进行内存申请释放时优先和缓存交互,提高效率。
图3为tcmalloc和jemalloc进行内存分配和释放时所采用的内存分层结构示意图。tcmalloc和jemalloc作为通用的内存管理器在设计上考虑的通用的场景,在内存分类以及内存空间层级划分方式上兼顾了大多数的业务应用场景,采用的是预先设置固定的可分配内存块尺寸及级别的方式,无法实现针对具体某个业务应用的内存分配和管理的优化。
在基于Ceph的存储集群中,不同的实例,例如元数据服务(MetaData Server,MDS)实例、对象存储设备(Object Storage Device,OSD)守护进程实例等,在不同业务场景下,对内存的申请和释放会随着业务的不同产生较大的差异。如果在实例运行过程中,实例频繁申请的内存大小不在预先设置的可分配内存块大小范围内,随着实例的运行,可能会产生大量的内存碎片,造成内存浪费。另外,Ceph存储集群通过直接加载类似tcmalloc或者jemalloc的动态或静态连接库进行内存管理,不同存储集群的实例在申请内存时,不会对内存分配进行隔离,在实际业务场景中,可能会存在实例A申请的内存又分配给了实例B的情况,从而导致内存分配冲突及程序错乱。
针对上述技术问题,本公开提出一种内存管理方法,可应用于各种应用和业务系统中的业务实例,例如应用于Ceph分布式存储系统的OSD守护进程、MDS实例当中,以提高内存使用效率,减少内存碎片以及避免内存分配上的冲突。
本公开为了适配不同的业务场景对不同尺寸的内存分配需求,对内存空间的层级结构、分配及管理方法进行了改进,对不同尺寸的内存块进行分类分组管理,允许基于内存分类表的统计结果对内存块分类进行动态调整,从而实现内存管理与业务应用的适配,提高内存利用率。另外,通过为不同实例指定不同的内存块分组,实现内存分配隔离,从而有效解决不同实例内存申请可能产生冲突的问题。
图4为本公开一实施例提供的内存管理方法所采用的内存组织结构示意图,本公开将内存分配的层级分为4个层级,分别为:
内存池(MemPool):该层级内部包括若干原始内存块(简称Blk),Blk是通过操作系统向物理存储空间申请的预设固定尺寸的原始内存块,Blk的大小可配置,例如默认Blk大小可以为8M,也可以配置为16M、32M等。在MemPool初始化时通过调用操作系统的内存分配函数(例如mmap()方法)申请分配一定数量的Blk放入MemPool中,随着上层业务的使用当MemPool中Blk用完时可以继续从系统申请新的Blk以扩充MemPool的内存空间。MemPool初始化时Blk数量的初始值和最大值可通过配置文件设定。
本地缓存(LocalCache):为了提高线程对内存的分配和释放效率,避免不同线程直接从Part分配或释放内存的互斥锁管理的开销,针对线程提供专用于线程本身的内存空间,将这一级的内存空间称为LocalCache即本地缓存。对于Localcache层的内存,线程分配或释放时,直接对自己的LocalCache进行操作即可。LocalCache内部是由切片管理内存块Slab切分的内存片Slice组成,LocalCache大小即LocalCache中可管理的Slice的最大个数可通过配置文件进行配置。
切片管理内存块Slab是Blk经过初始化后得到的一种具有Slice管理功能的数据结构,其中包括数据结构信息(例如Slice起始位置、Slice的数量等信息)和多个内存片Slice,一个Slab中所包含的所有Slice的大小都相同。在初始化分配时,可通过从MemPool中读取Blk,将Blk切分为Slice后得到Slab。
Localcache的空间是从Slab加载进去的(就是把Slab中的Slice加载到Localcache中)。Localcache中Slice的大小是一样的,Slice的大小取决于当前Localcache对应的Part,一个Part对应一种大小的Slice。可以通过配置文件配置LocalCache的大小和所对应的Part分类,Part分类由Part中的Slice的大小决定,例如当Part中的Slice的大小为8B时,该Part的分类即指Slice为8B的Part。
块管理对象(简称Part):Part是由多个具有相同尺寸的切片管理内存块Slab组成的内存管理对象,其内部包括三个链表(也可采用列表、数组等形式)分别为:无空闲链表emptylist、部分空闲链表partiallist、全空闲链表fulllist,三个链表中的元素是都是相同大小的切片管理内存块Slab。
无空闲链表Emptylist中的所有Slab都是已将内部内存片Slice全部分配出去的Slab;
部分空闲链表Partiallist中的所有Slab都是已将内部部分内存片Slice分配出去,还有部分Slice未被分配出去的Slab;
全空闲链表Fulllist中的所有Slab都是全部内存片Slice都未被分配的Slab。
本公开实施例中,每个Part对应一种尺寸的内存片(Slice),即一个Part内部的所有Slab所管理的Slice都具有相同的尺寸大小,不同分类的Part内部的Slice大小不同。当上层应用需要某种大小的内存空间时,可根据申请的内存空间的大小判断与哪个Part中的Slice大小适配,从适配的Part申请即可。本公开通过对不同尺寸的内存片以Slab的组织形式进行分类管理,可提高内存的申请释放效率,减少了内存碎片。
块管理对象组(简称Group):Group由多个对应不同尺寸Slice的Part组成。例如,可以默认Group包含20个Part,每个Part所对应的Slice尺寸以2的指数次幂递增,例如Part1对应Slice尺寸为8字节,Part2对应Slice尺寸为16字节,…,Part20对应的Slice尺寸为4兆字节。为了提高灵活性,可针对不同的业务通过配置文件配置Part的尺寸分档,例如可以通过指定增量函数的方式配置Part对应的Slice尺寸的递增方式从而以某个起始尺寸为基础配置多个不同分类大小的Part以适配不同大小的内存分配请求,或也可以固定配置的方式配置某个尺寸的Part以适配某个应用大量的针对该尺寸Slice的内存分配需求。
本公开实施例,允许通过自动或手动配置的方式为不同的上层应用实例指定不同配置的Group,使得不同实例拥有自己的专属Group,不会与其他实例在内存分配上出现交互,从而有效解决不同实例间内存分配可能出现的冲突的问题。
在启动应用实例之前,基于优化和管理的目的,可通过配置文件对各层级的内存参数进行配置,如果不做配置,则实例启动后可采用默认配置。实例在内存中加载启动的过程中,需对内存各层级进行初始化,初始化时,首先读取配置文件,若配置文件中设置有非默认的配置参数,则使用非默认的配置参数,如果没有配置文件或配置文件中不存在非默认的配置参数,则默认配置。
以Part的初始化为例,本公开实施例可允许用户手动在配置文件中配置Part的初始化参数,同时本公开实施例也可提供预置的Part分类表作为Part的默认配置参数。Part的配置参数示例如下:
{sliceSize,localcacheSize,minSliceCnt,maxSliceCnt,attr}
其中,sliceSize为当前Part中Slice的大小;
localcacheSize为LocalCache的大小(包含的Slice的个数);
minSliceCnt为Part创建时最小的Slice数量,决定初始从MemPool中获取多少个Blk;
maxSliceCnt为Part可容纳的最大Slice数量,可用来判断内部扩充逻辑是否合理。
attr为Part的属性配置,内部逻辑使用。
以下为本公开一实施例提供的Part分类表的示例,其中以“DEFAULT”为前缀的参数为预定义的常量:
{8,512*DEFAULT_PART_CACHE_SIZE,DEFAULT_PART_MIN_SLICE,DEFAULT_PART_MAX_SLICE,DEFAULT_PART_ATTR},
{16,256*DEEAULT_PART-CACHE_SIZE,DEFAULT_PART_MIN_SLICE,DEFAULT_PART_MAX_SLICE,DEFAULT_PART_ATTR},
{32,128*DEFAULT_PART_CACHE_SIZE,DEFAULT_PART_MIN_SLICE,DEFAULT_PART_MAX_SLICE,DEFAULT_PART_ATTR},
{64,64*DEFAULT_PART_CACHE_SIZE,DEFAULT_PART_MIN_SLICE,DEFAULT_PART_MAX_SLICE,DEFAULT_PART_ATTR},
{128,32*DEFAULT_PART_CACHE_SIZE,DEFAULT_PART_MIN_SLICE,DEFAULT_PART_MAX_SLICE,DEFAULT_PART_ATTR},
{256,16*DEFAULT_PART_CACHE_SIZE,DEFAULT-PART_MIN_SLICE,DEFAULT_PART_MAX_SLICE,DEFAULT_PART_ATTR},
{512,16*DEFAULT_PART_CACHE_SIZE,DEFAULT_PART_MIN_SLICE,DEFAULT_PART_MAX_SLICE,DEFAULT_PART_ATTR},
{1024,DEFAULT_PART_CACHE_SIZE,DEFAULT_PART_MIN_SLICE,DEFAULT-PART_MAX_SLICE,DEFAULT_PART_ATTR},
{2048,DEFAULT_PART_CACHE_SIZE,DEFAULT_PART_MIN_SLICE,DEFAULT_PART_MAX_SLICE,DEFAULT_PART_ATTR},
{4096,DEFAULT-PART_CACHE_SIZE,DEFAULT_PART_MIN_SLICE,DEFAULT_PART_MAX_SLICE,DEFAULT_PART_ATTR},
{8192,DEFAULT_PART_CACHE_SIZE,DEFAULT_PART_MIN_SLICE,DEFAULT_PART_MAX_SLICE,DEFAULT_PART_ATTR},
{16384,2*DEFAULT-PART_CACHE_SIZE,DEFAULT_PART_MIN_SLICE,DEFAULT_PART_MAX_SLICE,DEFAULT_PART_ATTR},
{32768,DEFAULT_PART_CACHE_SIZE,DEFAULT_PART_MIN_SLICE,DEFAULT_PART_MAX_SLICE,DEFAULT_PART_ATTR},
{65536,DEFAULT_PART_CACHE_SIZE/2,DEFAULT_PART-MIN_SLICE,DEFAULT_PART-MA×_SLICE,DEFAULT-PART_ATTR},
{131072,DEFAULT_PART_CACHE-SIZE/2,DEFAULT_PART_MIN_SLICE,DEFAULT_PART_MAX_SLICE,DEFAULT_PART_ATTR},
{262144,DEFAULT_PART-CACHE-SIZE/8,DEFAULT_PART-MIN_SLICE,DEFAULT_PART_MA×-SLICE,DEFAULT-PART_ATTR},|
{524288,DEFAULT_PART_CACHE_SIZE/4,DEFAULT_PART_MIN_SLICE/2,DEFAULT_PART_MAX_SLICE,PART_ATTR_NO_CACHE},
{1048576,DEFAULT_PART_CACHE_SIZE/4,DEFAULT_PART_MIN_SLICE/4,DEFAULT_PART_MAX_SLICE,DEFAULT-PART_ATTR},
{2097152,DEFAULT_PART_CACHE_sIZE/4,DEFAULT_PART_MIN_SLICE/8,DEFAULT_PART_MAX_SLICE,PART_ATTR_NO_CACHE},
{4194304,DEFAULT_PART_CACHE_SIZE/4,DEFAULT_PART_MIN_SLICE/16,DEFAULT_PART_MAX_SLICE,PART_ATTR_NO_CACHE},
本公开实施例也可以将默认配置参数、非默认配置参数(需要特殊指定)和动态配置相结合的方式实现内存配置参数的调整,以提供更大的灵活性。
例如,针对Group的初始化,如果没有手动在配置文件中为Group指定所包括的Part类型,则按预置的Part分类表(即默认配置参数)中的Part分类的配置参数初始化Group,为Group创建Part分类表中所有的Part分类;如果既有默认配置参数又有非默认配置参数,则为Group既创建非默认的Part分类(例如用户手动添加的Part分类),也为Group创建预置的Part分类表中的Part分类。
为了实现针对不同业务的内存优化,本公开一实施例允许对内存参数进行动态配置,图5为本公开一实施例提供的对Part分类配置进行动态调整的方法步骤示意图,动态调整的方法为:
步骤501.在初始状态下,各业务实例中的Group使用预设的Part分类表进行初始化;
业务实例在对Group进行初始化时,会读取Part分类表创建Group当中的Part,在业务初始部署的情况下,首先为业务提供通用的预置Part分类表。
步骤502.针对每个业务统计分析业务实例的内存申请情况,生成与业务对应的Part分类表;
在实际业务场景下,统计每种业务实例的内存申请的实际情况,对统计数据进行分析,进而将申请频率高的内存空间大小分类细化成不同的Part分类或者单独设置某个规格的Part分类,提高内存的使用率。例如,在实际环境中,当集群针对某业务场景时,可配置对该业务场景更加有利的一组Part分类,当集群在另一种业务场景下时,又可以配置对另一种业务更加有利的一组Part分类,从而实现针对不同业务实例的Part分类表的优化。
以对象存储设备OSD的业务实例为例,在集群中的OSD守护进程使用本公开提供的内存管理方法的情况下,通过日志文件中的内存统计信息就可以得到OSD分配内存的具体情况。例如,经过分析内存分配数据发现OSD申请80K的内存频率较高。假设默认配置下,在64K的Part分类之后是128K的Part分类,业务实例若申请80K的内存空间,只能从128K的Part中申请分配Slice,造成了内存浪费。因此,如果80K的内存空间的分配确实数量巨大,可以新增一个80K的Part分类,或者结合其他内存分配情况,在64K和128K的Part分类之间增加Part分类来减少内存的浪费。
Part分类表的动态配置功能可通过一个动态配置组件来完成,例如通过周期性运行该动态配置组件对业务实例的内存申请情况进行统计分析,由该动态配置组件自动生成每个业务对应的Part分类表。例如,为业务1生成Part分类表1,为业务2生成Part分类表2,为业务3生成Part分类表3,依次类推。
步骤503.基于统计分析结果,调整业务对应的Part分类表的配置;
例如,在业务的配置文件中包括Part分类表配置项,用于指定该业务所使用的Part分类表,在初始情况下,给配置项都指向默认的Part分类表。在业务运行一段时间后,动态配置组件生成针对每个业务的新的Part分类表,动态配置组件根据统计分析结果自动更新某个或某些业务的配置文件中的Part分类表配置项,使其指向为该业务生成的新的Part分类表,从而实现Part分类表的动态配置。
步骤504.业务实例重启后,使用各自的Part分类表进行初始化。
在更新Part分类表后,动态配置组件重启业务实例,业务实例重启后会重新加载配置文件,按照配置文件的Part分类创建对应Group和Part。
本公开实施例中,业务实例启动时所进行的有关内存配置参数包括但不限于Blk的大小、LocalCache的大小,MemPool的大小,Group的配置参数、Part分类表等。
图6为本公开一实施例提供的内存管理方法中内存申请的步骤流程图,该步骤流程图示例了在应用实例启动之后,针对实例的内存分配请求的处理逻辑,该方法包括:
步骤601.内存分配函数被调用后,基于所申请的内存空间的大小适配Part;
在实例启动时,实例需首先加载本公开提供的内存管理动态库,由本公开提供的内存管理动态库中的内存分配函数来接管操作系统原有的内存分配函数(例如malloc函数)。
在实例需要申请内存的时候,会调用内存分配函数来申请内存,若将负责内存分配的程序功能模块看做一个装置,则业务实例调用内存分配函数相当于实例向该装置发送了内存分配请求。如果内存分配函数执行成功,则获取到实例所需的内存空间,如果内存分配函数执行失败,则返回执行失败的信息。
步骤602.获取LocalCache当前的内存分配情况,尝试从LocalCache中分配所申请的内存空间;
通常LocalCache中都会预留有一定数量的内存空间供业务实例申请分配。例如可在每次执行完内存分配函数后,判断是否有一定数量的预留空间,如果没有足够的预留空间,则预先从上一级存储空间中补充。
步骤603.判断LocalCache中是否有充足的内存空间以供分配;如果LocalCache中有充足的内存空间以供分配,则内存分配函数返回所申请的内存空间后函数结束;如果没有,则执行步骤604。
由于LocalCache中的Slice是取自于Part,因此需首先进行申请的内存空间与Part分类的适配,然后再看LocalCache中是否存在指定Part分类的Slice,当LocalCache中有适配的Slice以供分配时,将空闲的Slice分配出去并记录分配信息。
步骤604.获取适配的Part的信息,尝试从Part中分配;
步骤605.判断Part中的partiallist中是否有充足的可分配空间以供分配,如果有,则执行步骤606,否则执行607;
Part中的partiallist中的Slab是已将内部部分内存片Slice分配出去,还有部分Slice未被分配出去的Slab,因此首先从partiallist进行分配,若partiallist中的Slab的Slice都已被分配出去了,则将给Slab移动到emptylist中。当partiallist中没有Slab时,从fulllist取Slab填充partiallist。当fulllist中没有Slab时,从MemPool申请Blk并填充fullist,MemPool中Blk也不足时,通过系统调用mmap从系统分配内存填充MemPool。
步骤606.从partiallist中获取存储空间填充到LocalCache中,内存分配函数返回所申请的内存空间后函数结束;
步骤607.判断Part中的fullist中是否有充足的可分配空间以供分配,如果有,则执行步骤608,否则执行609;
步骤608.从fullist中获取存储空间填充到partiallist,然后再从partialist中获取所申请的内存空间填充到LocalCache,内存分配函数返回所申请的内存空间后函数结束。
步骤609.获取MemPool的存储信息,尝试从MemPool中获取存储空间;
步骤610.判断MemPool的存储空间是否充足,若充足则执行步骤611,否则执行612;
步骤611.从MemPool中获取存储空间填充到fullist,然后从fullist中获取所申请的存储空间填充到partiallist,然后再从partialist中获取所申请的内存空间填充到LocalCache,内存分配函数返回所申请的内存空间后函数结束。
步骤612.从操作系统获取一定数量的原始内存块Blk;
步骤613.将获取的Blk填充到MemPool中,从MemPool中获取存储空间填充到fullist,然后从fullist中获取存储空间填充到partiallist,然后再从partialist中获取所申请的内存空间填充到LocalCache,内存分配函数返回所申请的内存空间后函数结束。
图7为本公开一实施例提供的内存管理方法中内存释放的步骤流程图,该步骤流程图示例了在应用实例启动之后,针对实例释放内存的处理逻辑,该方法包括:
步骤710.业务实例通过内存释放函数请求释放不再使用的内存空间;
同理,在实例启动时,实例需首先加载本公开提供的内存管理动态库,由本公开提供的内存管理动态库中的内存释放函数来接管操作系统原有的内存释放函数(例如free函数)。
步骤711.首先尝试将内存释放回LocalCache;
由于本公开实施例中,在申请内存时是从Localcache分配的,因此释放时也优先释放到Localcache中。
步骤712.判断如果释放到LocalCache中,LocalCache是否会溢出即是否会超过LocalCache预设的大小,如果是则执行步骤713,否则内存释放函数执行成功,释放流程结束。
步骤713.尝试将内存释放回Part;
本公开实施例中MemPool中的每个Blk都是相同大小且是对齐的。当Localcache满后,根据所释放的Slice的地址可以计算出该Slice属于哪个Part的哪个Slab,计算出后就可以将所释放的Slice放回Slab中,当Slab中的Slice全部释放回来后就可以把这个Slab移到fulllist中。
步骤714.判断所释放的内存到partiallist的指定Slab后,该Slab是否已满即Slab中的Slice都未使用,若是则执行步骤715,否则内存释放函数执行成功,释放流程结束。
步骤715.将已满的Slab移动到fullist中;
步骤716.判断fullist是否已满即fullist中的Slab是否已达到预设的最大Slab个数,造成Slab溢出,若是则执行步骤717,否则内存释放函数执行成功,释放流程结束。
步骤717.将溢出的Slab释放到MemPool中;
步骤718.判断释放到MemPool后,是否会造成MemPool所管理的Blk溢出,若是则执行步骤719,否则内存释放函数执行成功,释放流程结束。
步骤719.将溢出的Blk释放回操作系统,内存释放函数执行成功,释放流程结束。
本公开提供的内存管理方法通过对内存进行分类分级管理,使业务实例所申请的内存空间尽可能地适配所提供的不同尺寸类型的内存块,通过将不同块分类及将不同大小的内存块分类组成组,将组与业务实例绑定,针对不同实例实现内存管理上的隔离,从而提高了内存使用率,避免了不同实例在内存分配上可能产生的冲突。
图8为本公开一实施例提供的一种电子设备结构示意图,该设备800包括:诸如中央处理单元(CPU)的处理器810、通信总线820以及存储介质830。其中,处理器810与存储介质830可以通过通信总线820相互通信。存储介质830内存储有计算机程序,当该计算机程序被处理器810执行时即可实现本公开提供的内存管理方法的各步骤的功能。
其中,存储介质可以包括随机存取存储器(Random Access Memory,RAM),也可以包括非易失性存储器(Non-Volatile Memory,NVM),例如至少一个磁盘存储器。另外,存储介质还可以是至少一个位于远离前述处理器的存储装置。处理器可以是通用处理器,包括中央处理器(Central Processing Unit,CPU)、网络处理器(Network Processor,NP)等;还可以是数字信号处理器(Digital Signal Processing,DSP)、专用集成电路(ApplicationSpecific Integrated Circuit,ASIC)、现场可编程门阵列(Field-Programmable GateArray,FPGA)或其他可编程逻辑器件、分立门或者晶体管逻辑器件、分立硬件组件。
应当认识到,本公开的实施例可以由计算机硬件、硬件和软件的组合、或者通过存储在非暂时性存储器中的计算机指令来实现或实施。所述方法可以使用标准编程技术,包括配置有计算机程序的非暂时性存储介质在计算机程序中实现,其中如此配置的存储介质使得计算机以特定和预定义的方式操作。每个程序可以以高级过程或面向对象的编程语言来实现以与计算机系统通信。然而,若需要,该程序可以以汇编或机器语言实现。在任何情况下,该语言可以是编译或解释的语言。此外,为此目的该程序能够在编程的专用集成电路上运行。此外,可按任何合适的顺序来执行本公开描述的过程的操作,除非本公开另外指示或以其他方式明显地与上下文矛盾。本公开描述的过程(或变型和/或其组合)可在配置有可执行指令的一个或多个计算机系统的控制下执行,并且可作为共同地在一个或多个处理器上执行的代码(例如,可执行指令、一个或多个计算机程序或一个或多个应用)、由硬件或其组合来实现。所述计算机程序包括可由一个或多个处理器执行的多个指令。
进一步,所述方法可以在可操作地连接至合适的任何类型的计算平台中实现,包括但不限于个人电脑、迷你计算机、主框架、工作站、网络或分布式计算环境、单独的或集成的计算机平台、或者与带电粒子工具或其它成像装置通信等等。本公开的各方面可以以存储在非暂时性存储介质或设备上的机器可读代码来实现,无论是可移动的还是集成至计算平台,如硬盘、光学读取和/或写入存储介质、RAM、ROM等,使得其可由可编程计算机读取,当存储介质或设备由计算机读取时可用于配置和操作计算机以执行在此所描述的过程。此外,机器可读代码,或其部分可以通过有线或无线网络传输。当此类媒体包括结合微处理器或其他数据处理器实现上文所述步骤的指令或程序时,本公开所述的发明包括这些和其他不同类型的非暂时性计算机可读存储介质。当根据本公开所述的方法和技术编程时,本公开还包括计算机本身。
以上所述仅为本公开的实施例而已,并不用于限制本公开。对于本领域技术人员来说,本公开可以有各种更改和变化。凡在本公开的精神和原理之内所作的任何修改、等同替换、改进等,均应包含在本公开的保护范围之内。
Claims (12)
1.一种内存管理方法,其特征在于,所述方法用于实现实例的内存分配,所述方法包括:
基于实例所申请的内存空间的大小适配块管理对象Part分类;其中,Part为由多个具有相同尺寸的切片管理内存块Slab组成的内存管理对象;所述Slab中包括由原始内存块Blk切分的多个相同大小的内存片Slice;所述Part依据Slice的大小分类;
从本地缓存LocalCache中包括的与适配的Part分类一致的空闲内存片Slice中为实例分配内存;
当所述LocalCache中的空间不足时,从适配的Part分类对应的Part所管理的具有空闲Slice的Slab中为实例分配内存;
当适配的Part中无空闲的Slice时,从内存池MemPool中获取原始内存块Blk,将Blk初始化为适配的Part分类对应的Slab,将Slab加入到适配的Part中,再从适配的Part中为实例分配内存。
2.根据权利要求1所述的方法,其特征在于,所述Part包括:
无空闲链表Emptylist,其中的所有Slab都是已将内部内存片Slice全部分配出去的Slab;
部分空闲链表Partiallist,其中的所有Slab都是已将内部部分内存片Slice分配出去,还有部分Slice未被分配出去的Slab;
全空闲链表Fulllist,其中的所有Slab都是全部内存片Slice都未被分配的Slab;
所述从适配的Part分类对应的Part所管理的具有空闲Slice的Slab中为实例分配内存的方法为:
首先判断Partiallist中是否有充足的空闲的Slice可供分配,如果有则从对应的Slab中分配,如果没有则从Fulllist中获取未被分配的Slab填充到Partiallist中,然后再从填充的Slab中分配。
3.根据权利要求2所述的方法,其特征在于,所述方法还用于实现实例的内存释放,内存释放的步骤包括:
在将释放的内存释放回LocalCache不会导致LocalCache溢出的情况下,将释放的内存释放回LocalCache;
在释放回LocalCache会导致LocalCache溢出的情况下,将释放的内存释放回Part;
在释放回Part会导致Part溢出的情况下,将释放的内存释放回MemPool;
在释放回MemPool会导致MemPool溢出的情况下,将释放的内存释放回操作系统。
4.根据权利要求1所述的方法,其特征在于,所述方法还包括:
所述实例与块管理对象组Group绑定,所述Group由多个不同分类的Part组成;
所述基于所申请的内存空间的大小适配块管理对象Part分类具体为:在所述Group所包含的Part分类中进行适配;
所述适配的Part为所述Group中的Part。
5.根据权利要求4所述的方法,其特征在于,
在实例启动时,使用Part分类表对所述Group进行初始化;
所述Part分类表采用默认配置和/或采用如下动态配置方法:
对实例申请的不同大小的内存空间的频率进行统计分析;
基于预设门限,在默认Part分类表中新增频率高于预设门限的内存空间大小对应的Part分类。
6.一种内存管理装置,其特征在于,所述装置用于实现实例的内存分配,该装置包括:
适配模块,用于基于所申请的内存空间的大小适配块管理对象Part分类;其中,Part为由多个具有相同尺寸的切片管理内存块Slab组成的内存管理对象;所述Slab中包括由原始内存块Blk切分的多个相同大小的内存片Slice;所述Part依据Slice的大小分类;
本地缓存分配模块,用于从本地缓存LocalCache中包括的与适配的Part分类一致的空闲内存片Slice中为实例分配内存;
块管理对象分配模块,用于当所述LocalCache中的空间不足时,从适配的Part分类对应的Part所管理的具有空闲Slice的Slab中为实例分配内存;
内存池分配模块,用于在适配的Part中无空闲的Slice时,从内存池MemPool中获取原始内存块Blk,将Blk初始化为适配的Part分类对应的Slab,将Slab加入到适配的Part中,再从适配的Part中为实例分配内存。
7.根据权利要求6所述的装置,其特征在于,所述块管理对象分配模块中包括:
无空闲链表Emptylist,其中的所有Slab都是已将内部内存片Slice全部分配出去的Slab;
部分空闲链表Partiallist,其中的所有Slab都是已将内部部分内存片Slice分配出去,还有部分Slice未被分配出去的Slab;
全空闲链表Fulllist,其中的所有Slab都是全部内存片Slice都未被分配的Slab;
所述块管理对象分配模块从适配的Part分类对应的Part所管理的具有空闲Slice的Slab中为实例分配内存的方法为:
首先判断Partiallist中是否有充足的空闲的Slice可供分配,如果有则从对应的Slab中分配,如果没有则从Fulllist中获取未被分配的Slab填充到Partiallist中,然后再从填充的Slab中分配。
8.根据权利要求7所述的装置,其特征在于,所述装置还用于实现实例的内存释放,该装置还包括:
第一释放模块,用于在将释放的内存释放回LocalCache不会导致LocalCache溢出的情况下,将释放的内存释放回LocalCache;
第二释放模块,用于在释放回LocalCache会导致LocalCache溢出的情况下,将释放的内存释放回Part;
第三释放模块,用于在释放回Part会导致Part溢出的情况下,将释放的内存释放回MemPool;
第四释放模块,用于在释放回MemPool会导致MemPool溢出的情况下,将释放的内存释放回操作系统。
9.根据权利要求6所述的装置,其特征在于,
所述实例与块管理对象组Group绑定,所述Group由多个不同分类的Part组成;
所述适配模块在所述Group所包含的Part分类中进行Part分类的适配,所述适配的Part为所述Group中的Part。
10.根据权利要求9所述的装置,其特征在于,所述装置还包括:
初始化模块,用于在实例启动时,使用Part分类表对所述Group进行初始化;所述Part分类表采用默认配置和/或采用动态配置;
动态配置模块,用于在Part分类表采用动态配置的情况下,对实例申请的不同大小的内存空间的频率进行统计分析;以及基于预设门限,在默认Part分类表中新增频率高于预设门限的内存空间大小对应的Part分类。
11.一种电子设备,其特征在于,包括处理器、通信接口、存储介质和通信总线,其中,处理器、通信接口、存储介质通过通信总线完成相互间的通信;
存储介质,用于存放计算机程序;
处理器,用于执行存储介质上所存放的计算机程序时,实施权利要求1至5任一项所述的方法步骤。
12.一种存储介质,其上存储有计算机程序,其特征在于,所述计算机程序当被处理器执行时实施如权利要求1至5中任一项所述的方法步骤。
Priority Applications (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN202110562803.6A CN113515376A (zh) | 2021-05-24 | 2021-05-24 | 一种内存管理方法、装置、电子设备及存储介质 |
Applications Claiming Priority (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN202110562803.6A CN113515376A (zh) | 2021-05-24 | 2021-05-24 | 一种内存管理方法、装置、电子设备及存储介质 |
Publications (1)
Publication Number | Publication Date |
---|---|
CN113515376A true CN113515376A (zh) | 2021-10-19 |
Family
ID=78064687
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
CN202110562803.6A Pending CN113515376A (zh) | 2021-05-24 | 2021-05-24 | 一种内存管理方法、装置、电子设备及存储介质 |
Country Status (1)
Country | Link |
---|---|
CN (1) | CN113515376A (zh) |
Cited By (2)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN116501511A (zh) * | 2023-06-29 | 2023-07-28 | 恒生电子股份有限公司 | 内存尺寸处理方法、装置、电子设备及存储介质 |
TWI841171B (zh) | 2022-09-19 | 2024-05-01 | 聯詠科技股份有限公司 | 控制器電路及車載顯示系統 |
-
2021
- 2021-05-24 CN CN202110562803.6A patent/CN113515376A/zh active Pending
Cited By (3)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
TWI841171B (zh) | 2022-09-19 | 2024-05-01 | 聯詠科技股份有限公司 | 控制器電路及車載顯示系統 |
CN116501511A (zh) * | 2023-06-29 | 2023-07-28 | 恒生电子股份有限公司 | 内存尺寸处理方法、装置、电子设备及存储介质 |
CN116501511B (zh) * | 2023-06-29 | 2023-09-15 | 恒生电子股份有限公司 | 内存尺寸处理方法、装置、电子设备及存储介质 |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
US10242022B1 (en) | Systems and methods for managing delayed allocation on clustered file systems | |
US11231955B1 (en) | Dynamically reallocating memory in an on-demand code execution system | |
KR101357397B1 (ko) | 데이터 프로세싱 시스템의 메모리 사용을 추적하는 방법 | |
JP6370218B2 (ja) | メモリ管理方法、コンピュータシステム、コンピュータプログラム及び記憶媒体 | |
CN108572845B (zh) | 分布式微服务集群的升级方法及相关系统 | |
TWI604378B (zh) | 用於新應用程式之記憶體管理模型與介面 | |
US8850156B2 (en) | Method and system for managing virtual machine storage space and physical host | |
CN112214293A (zh) | 一种无服务器架构下业务部署的方法和函数管理平台 | |
JP5980916B2 (ja) | コンピュータにより実行される方法及びコンピュータシステム | |
CN107066498B (zh) | 键值kv存储方法和装置 | |
US20110225342A1 (en) | Opportunistic page caching for virtualized servers | |
WO2017050064A1 (zh) | 共享内存数据库的内存管理方法及装置 | |
US20220283846A1 (en) | Pod deployment method and apparatus | |
CN111045802B (zh) | Redis集群组件调度系统及方法、平台设备 | |
CN112860387A (zh) | 分布式任务调度方法、装置、计算机设备及存储介质 | |
CN113849260A (zh) | 一种实例的处理核分配方法及装置 | |
CN113515376A (zh) | 一种内存管理方法、装置、电子设备及存储介质 | |
US20200409833A1 (en) | Reducing fragmentation of computer memory | |
CN110471759B (zh) | 一种多核嵌入式处理器内存实时动态管理方法 | |
US11340832B2 (en) | Concept for controlling a memory performance in a computer system | |
CN106537321B (zh) | 存取文件的方法、装置和存储系统 | |
US20220318042A1 (en) | Distributed memory block device storage | |
CN114518962A (zh) | 内存的管理方法及装置 | |
CN115827745A (zh) | 内存数据库集群的实现方法、装置及内存数据库集群 | |
CN114116230A (zh) | 一种资源管理方法、装置、设备、介质及产品 |
Legal Events
Date | Code | Title | Description |
---|---|---|---|
PB01 | Publication | ||
PB01 | Publication | ||
SE01 | Entry into force of request for substantive examination | ||
SE01 | Entry into force of request for substantive examination |