Linux中动态内存的分配与回收(heap, buddy system, stab)

2023-11-17

1.malloc 和free的原理(http://m.blog.csdn.net/article/details?id=39496057)

从操作系统角度来看,进程分配内存有两种方式,分别由两个系统调用完成:brk和mmap(不考虑共享内存)。

1、brk是将数据段(.data)的最高地址指针_edata往高地址推;

2、mmap是在进程的虚拟地址空间中(堆和栈中间,称为文件映射区域的地方)找一块空闲的虚拟内存

     这两种方式分配的都是虚拟内存,没有分配物理内存在第一次访问已分配的虚拟地址空间的时候,发生缺页中断,操作系统负责分配物理内存,然后建立虚拟内存和物理内存之间的映射关系。

在标准C库中,提供了malloc/free函数分配释放内存,这两个函数底层是由brk,mmap,munmap这些系统调用实现的

情况一、malloc小于128k的内存,使用brk分配内存,将_edata往高地址推(只分配虚拟空间,不对应物理内存(因此没有初始化),第一次读/写数据时,引起内核缺页中断,内核才分配对应的物理内存,然后虚拟地址空间建立映射关系)

情况二、malloc大于128k的内存,使用mmap分配内存,在堆和栈之间找一块空闲内存分配(对应独立内存,而且初始化为0)

 这样子做主要是因为::
      brk分配的内存需要等到高地址内存释放以后才能释放(例如,在B释放之前,A是不可能释放的,这就是内存碎片产生的原因,什么时候紧缩看下面),而mmap分配的内存可以单独释放。
B对应的虚拟内存和物理内存都没有释放,因为只有一个_edata指针,如果往回推,那么D这块内存怎么办呢
当然,B这块内存,是可以重用的,如果这个时候再来一个40K的请求,那么malloc很可能就把B这块内存返回回去了。 

 当最高地址空间的空闲内存超过128K(可由M_TRIM_THRESHOLD选项调节)时,执行内存紧缩操作(trim)


内存池

C/C++中直接使用系统调用malloc/free、new/delete进行内存分配和释放,有以下弊端:

  1. 调用malloc/new,系统需要根据“最先匹配”、“最优匹配”或其他算法在内存空闲块表中查找一块空闲内存,调用free/delete,系统可能需要合并空闲内存块,这些会产生额外开销
  2. 频繁使用时会产生大量内存碎片,从而降低程序运行效率
  3. 容易造成内存泄漏

内存池(memory pool)是代替直接调用malloc/freenew/delete进行内存管理的常用方法,当我们申请内存空间时,首先到我们的内存池中查找合适的内存块,而不是直接向操作系统申请,优势在于:

  1. 比malloc/free进行内存申请/释放的方式快
  2. 不会产生或很少产生堆碎片
  3. 可避免内存泄漏
在启动的时候,一个内存池”(Memory Pool)分配一块很大的内存,并将会将这个大块(block)分成较小的块(smaller chunks)。每次你从内存池申请内存空间时,它会从先前已经分配的块(chunks)中得到,而不是从操作系统。

http://blog.csdn.net/shawngucas/article/details/6574863


LINUX内核内存管理kmalloc,vmalloc

在设备驱动程序或者内核模块中动态开辟内存,不是用malloc,而是kmalloc ,vmalloc,释放内存用的是kfree,vfree,kmalloc函数返回的是虚拟地址(线性地址). kmalloc特殊之处在于它分配的内存是物理上连续的,这对于要进行DMA的设备十分重要. 而用vmalloc分配的内存只是线性地址连续,物理地址不一定连续,不能直接用于DMA。

vmalloc函数的工作方式类似于kmalloc,只不过它分配的内存虚拟地址是连续的,而物理地址则无需连续。通过vmalloc获得的页必须一个一个地进行映射,效率不高, 因此,只在不得已(一般是为了获得大块内存)时使用。vmalloc函数返回一个指针,指向逻辑上连续的一块内存区,其大小至少为size。在发生错误 时,函数返回NULL。vmalloc可能睡眠,因此,不能从中断上下文中进行调用,也不能从其它不允许阻塞的情况下调用。要释放通过vmalloc所获 得的内存,应使用vfree函数

vmalloc和kmalloc区别大概可总结为:

      1,vmalloc分配的一般为高端内存,只有当内存不够的时候才分配低端内存;kmallco从低端内存分配。

      2,vmalloc分配的物理地址一般不连续,而kmalloc分配的地址连续,两者分配的虚拟地址都是连续的;

      3,vmalloc分配的一般为大块内存,而kmaooc一般分配的为小块内存,(一般不超过128k);



  slab分配器是Linux内存管理中非常重要和复杂的一部分,其工作是针对一些经常分配并释放的对象,如进程描述符等,这些对象的大小一般比较小,如果直接采用伙伴系统来进行分配和释放,不仅会造成大量的内碎片,而且处理速度也太慢。而slab分配器是基于对象进行管理的,相同类型的对象归为一类(如进程描述符就是一类),每当要申请这样一个对象,slab分配器就从一个slab列表中分配一个这样大小的单元出去,而当要释放时,将其重新保存在该列表中,而不是直接返回给伙伴系统。slab分配对象时,会使用最近释放的对象内存块,因此其驻留在CPU高速缓存的概率较高。

       用于描述和管理cache的数据结构是struct kmem_cache


还要介绍的一个数据结构就是struct array_cache。struct kmem_cache中定义了一个struct array_cache指针数组,数组的元素个数对应了系统的CPU数,和伙伴系统中的每CPU页框高速缓存类似,该结构用来描述每个CPU的本地高速缓存,它可以减少SMP系统中对于自旋锁的竞争。在每个array_cache的末端都用一个指针数组记录了slab中的空闲对象,分配对象时,采用LIFO方式,也就是将该数组中的最后一个索引对应的对象分配出去,以保证该对象还驻留在高速缓存中的可能性。实际上,每次分配内存都是直接与本地CPU高速缓存进行交互,只有当其空闲内存不足时,才会从kmem_list中的slab中引入一部分对象到本地高速缓存中,而kmem_list中的空闲对象也不足了,那么就要从伙伴系统中引入新的页来建立新的slab了,这一点也和伙伴系统的每CPU页框高速缓存很类似。
转载linux中内存分配

伙伴系统算法

  在实际应用中,经常需要分配一组连续的页框,而频繁地申请和释放不同大小的连续页框,必然导致在已分配页框的内存块中分散了许多小块的 空闲页框常见的Linux内核中内存分配 - leon - 我的奋斗这样,即使这些页框是空闲的,其他需要分配连续页框的应用也很难得到满足常见的Linux内核中内存分配 - leon - 我的奋斗

  为了避免出现这种情况,Linux内核中引入了伙伴系统算法(buddy system)常见的Linux内核中内存分配 - leon - 我的奋斗把所有的空闲页框分组为11个 块链表,每个块链表分别包含大小为1,2,4,8,16,32,64,128,256,512和1024个连续页框的页框块常见的Linux内核中内存分配 - leon - 我的奋斗最大可以申请1024个连 续页框,对应4MB大小的连续内存常见的Linux内核中内存分配 - leon - 我的奋斗每个页框块的第一个页框的物理地址是该块大小的整数倍常见的Linux内核中内存分配 - leon - 我的奋斗

  假设要申请一个256个页框的块,先从256个页框的链表中查找空闲块,如果没有,就去512个 页框的链表中找,找到了则将页框块分为2个256个 页框的块,一个分配给应用,另外一个移到256个页框的链表中常见的Linux内核中内存分配 - leon - 我的奋斗如果512个页框的链表中仍没有空闲块,继续向1024个页 框的链表查找,如果仍然没有,则返回错误常见的Linux内核中内存分配 - leon - 我的奋斗

  页框块在释放时,会主动将两个连续的页框块合并为一个较大的页框块常见的Linux内核中内存分配 - leon - 我的奋斗

  1.2.slab分 配器

  slab分配器源于 Solaris 2.4 的 分配算法,工作于物理内存页框分配器之上,管理特定大小对象的缓存,进行快速而高效的内存分配常见的Linux内核中内存分配 - leon - 我的奋斗

  slab分配器为每种使用的内核对象建立单独的缓冲区常见的Linux内核中内存分配 - leon - 我的奋斗Linux 内核已经采用了伙伴系统管理物理内存页框,因此 slab分配器直接工作于伙伴系 统之上常见的Linux内核中内存分配 - leon - 我的奋斗每种缓冲区由多个 slab 组成,每个 slab就是一组连续的物理内存页框,被划分成了固定数目的对象常见的Linux内核中内存分配 - leon - 我的奋斗根据对象大小的不同,缺省情况下一个 slab 最多可以由 1024个页框构成常见的Linux内核中内存分配 - leon - 我的奋斗出于对齐 等其它方面的要求,slab 中分配给对象的内存可能大于用户要求的对象实际大小,这会造成一定的 内存浪费常见的Linux内核中内存分配 - leon - 我的奋斗

  2.常用内存分配函数

  2.1.__get_free_pages

  unsigned long __get_free_pages(gfp_t gfp_mask, unsigned int order)

  __get_free_pages函数是最原始的内存分配方式,直接从伙伴系统中获取原始页框,返回值为第一个页框的起始地址常见的Linux内核中内存分配 - leon - 我的奋斗__get_free_pages在实现上只是封装了alloc_pages函 数,从代码分析,alloc_pages函数会分配长度为1<<order的 连续页框块常见的Linux内核中内存分配 - leon - 我的奋斗order参数的最大值由include/Linux/Mmzone.h文 件中的MAX_ORDER宏决定,在默认的2.6.18内 核版本中,该宏定义为10常见的Linux内核中内存分配 - leon - 我的奋斗也就是说在理论上__get_free_pages函 数一次最多能申请1<<10 * 4KB也就是4MB的 连续物理内存常见的Linux内核中内存分配 - leon - 我的奋斗但是在实际应用中,很可能因为不存在这么大量的连续空闲页框而导致分配失败常见的Linux内核中内存分配 - leon - 我的奋斗测试中,order为10时分配成功,order为11则返回错误常见的Linux内核中内存分配 - leon - 我的奋斗

  2.2.kmem_cache_alloc

  struct kmem_cache *kmem_cache_create(const char *name, size_t size,

  size_t align, unsigned long flags,

  void (*ctor)(void*, struct kmem_cache *, unsigned long),

  void (*dtor)(void*, struct kmem_cache *, unsigned long))

  void *kmem_cache_alloc(struct kmem_cache *c, gfp_t flags)

  kmem_cache_create/ kmem_cache_alloc是基于slab分配器的一种内存分配方式,适用于反复分配释放同一大小内存块的场合常见的Linux内核中内存分配 - leon - 我的奋斗首先用kmem_cache_create创建一个高速缓存区域,然后用kmem_cache_alloc从 该高速缓存区域中获取新的内存块常见的Linux内核中内存分配 - leon - 我的奋斗 kmem_cache_alloc一次能分配的最大内存由mm/slab.c文件中的MAX_OBJ_ORDER宏 定义,在默认的2.6.18内核版本中,该宏定义为5, 于是一次最多能申请1<<5 * 4KB也就是128KB的 连续物理内存常见的Linux内核中内存分配 - leon - 我的奋斗分析内核源码发现,kmem_cache_create函数的size参数大于128KB时会调用BUG()常见的Linux内核中内存分配 - leon - 我的奋斗测试结果验证了分析结果,用kmem_cache_create分 配超过128KB的内存时使内核崩溃常见的Linux内核中内存分配 - leon - 我的奋斗

  2.3.kmalloc

  void *kmalloc(size_t size, gfp_t flags)

  kmalloc是内核中最常用的一种内存分配方式,它通过调用kmem_cache_alloc函 数来实现常见的Linux内核中内存分配 - leon - 我的奋斗kmalloc一次最多能申请的内存大小由include/Linux/Kmalloc_size.h的 内容来决定,在默认的2.6.18内核版本中,kmalloc一 次最多能申请大小为131702B也就是128KB字 节的连续物理内存常见的Linux内核中内存分配 - leon - 我的奋斗测试结果表明,如果试图用kmalloc函数分配大于128KB的内存,编译不能通过常见的Linux内核中内存分配 - leon - 我的奋斗

  2.4.vmalloc

  void *vmalloc(unsigned long size)

  前面几种内存分配方式都是物理连续的,能保证较低的平均访问时间常见的Linux内核中内存分配 - leon - 我的奋斗但是在某些场合中,对内存区的请求不是很频繁,较高的内存访问时间也 可以接受,这是就可以分配一段线性连续,物理不连续的地址,带来的好处是一次可以分配较大块的内存常见的Linux内核中内存分配 - leon - 我的奋斗图3-1表 示的是vmalloc分配的内存使用的地址范围常见的Linux内核中内存分配 - leon - 我的奋斗vmalloc对 一次能分配的内存大小没有明确限制常见的Linux内核中内存分配 - leon - 我的奋斗出于性能考虑,应谨慎使用vmalloc函数常见的Linux内核中内存分配 - leon - 我的奋斗在测试过程中, 最大能一次分配1GB的空间常见的Linux内核中内存分配 - leon - 我的奋斗

  Linux内核部分内存分布

  2.5.dma_alloc_coherent

  void *dma_alloc_coherent(struct device *dev, size_t size,

  ma_addr_t *dma_handle, gfp_t gfp)

  DMA是一种硬件机制,允许外围设备和主存之间直接传输IO数据,而不需要CPU的参与,使用DMA机制能大幅提高与设备通信的 吞吐量常见的Linux内核中内存分配 - leon - 我的奋斗DMA操作中,涉及到CPU高速缓 存和对应的内存数据一致性的问题,必须保证两者的数据一致,在x86_64体系结构中,硬件已经很 好的解决了这个问题, dma_alloc_coherent和__get_free_pages函数实现差别不大,前者实际是调用__alloc_pages函 数来分配内存,因此一次分配内存的大小限制和后者一样常见的Linux内核中内存分配 - leon - 我的奋斗__get_free_pages分配的内 存同样可以用于DMA操作常见的Linux内核中内存分配 - leon - 我的奋斗测试结果证明,dma_alloc_coherent函 数一次能分配的最大内存也为4M常见的Linux内核中内存分配 - leon - 我的奋斗

  2.6.ioremap

  void * ioremap (unsigned long offset, unsigned long size)

  ioremap是一种更直接的内存“分配”方式,使用时直接指定物理起始地址和需要分配内存的大小,然后将该段 物理地址映射到内核地址空间常见的Linux内核中内存分配 - leon - 我的奋斗ioremap用到的物理地址空间都是事先确定的,和上面的几种内存 分配方式并不太一样,并不是分配一段新的物理内存常见的Linux内核中内存分配 - leon - 我的奋斗ioremap多用于设备驱动,可以让CPU直接访问外部设备的IO空间常见的Linux内核中内存分配 - leon - 我的奋斗ioremap能映射的内存由原有的物理内存空间决定,所以没有进行测试常见的Linux内核中内存分配 - leon - 我的奋斗

  2.7.Boot Memory

  如果要分配大量的连续物理内存,上述的分配函数都不能满足,就只能用比较特殊的方式,在Linux内 核引导阶段来预留部分内存常见的Linux内核中内存分配 - leon - 我的奋斗

  2.7.1.在内核引导时分配内存

  void* alloc_bootmem(unsigned long size)

  可以在Linux内核引导过程中绕过伙伴系统来分配大块内存常见的Linux内核中内存分配 - leon - 我的奋斗使用方法是在Linux内核引导时,调用mem_init函数之前 用alloc_bootmem函数申请指定大小的内存常见的Linux内核中内存分配 - leon - 我的奋斗如果需要在其他地方调用这块内存,可以将alloc_bootmem返回的内存首地址通过EXPORT_SYMBOL导 出,然后就可以使用这块内存了常见的Linux内核中内存分配 - leon - 我的奋斗这种内存分配方式的缺点是,申请内存的代码必须在链接到内核中的代码里才能使用,因此必须重新编译内核,而且内存管理系统 看不到这部分内存,需要用户自行管理常见的Linux内核中内存分配 - leon - 我的奋斗测试结果表明,重新编译内核后重启,能够访问引导时分配的内存块常见的Linux内核中内存分配 - leon - 我的奋斗

  2.7.2.通过内核引导参数预留顶部内存

  在Linux内核引导时,传入参数“mem=size”保留顶部的内存区间常见的Linux内核中内存分配 - leon - 我的奋斗比如系统有256MB内 存,参数“mem=248M”会预留顶部的8MB内存,进入系统后可以调用ioremap(0xF800000,0x800000)来申请这段内存常见的Linux内核中内存分配 - leon - 我的奋斗

  3.几种分配函数的比较

 

 

分配原理

最大内存

其他

__get_free_pages

直接对页框进行操作

4MB

适用于分配较大量的连续物理内存

kmem_cache_alloc

基于slab机制实现

128KB

适合需要频繁申请释放相同大小内存块时使用

kmalloc

基于kmem_cache_alloc实现

128KB

最常见的分配方式,需要小于页框大小的内存时可以使用

vmalloc

建立非连续物理内存到虚拟地址的映射

 

物理不连续,适合需要大内存,但是对地址连续性没有要求的场合

dma_alloc_coherent

基于__alloc_pages实现

4MB

适用于DMA操 作

ioremap

实现已知物理地址到虚拟地址的映射

 

适用于物理地址已知的场合,如设备驱动

alloc_bootmem

在启动kernel时,预留一段内存,内核看不见

 

小于物理内存大小,内存管理要求较高


1.kmalloc
   kmalloc内存分配和malloc相似,除非被阻塞否则他执行的速度非常快,而且不对获得空间清零.
说明:在用kmalloc申请函数后,要清零用memset()函数对申请的内存进行清零。

2. kamlloc函数原型:
#include
Void *kmalloc(size_t size, int flags);
(1)第一个参数是要分配的块的大小
(2)第二个参数是分配标志(flags),他提供了多种kmalloc的行为。
(3)第三个最常用的GFP_KERNEL;

A.表示内存分配(最终总是调用get_free_pages来实现实际的分配;这就是GFP前缀的由来)是代表运行在内核空间的进程执行的。使用GFP_KERNEL容许kmalloc在分配空闲内存时候如果内存不足容许把当前进程睡眠以等待。因此这时分配函数必须是可重入的。如果在进程上下文之外如:中断处理程序、tasklet以及内核定时器中这种情况下current进程不该睡眠,驱动程序该使用GFP_ATOMIC.
B.GFP_ATOMIC
用来从中断处理和进程上下文之外的其他代码中分配内存. 从不睡眠.
C.GFP_KERNEL
内核内存的正常分配. 可能睡眠.
D.GFP_USER
用来为用户空间页来分配内存; 它可能睡眠.
E.GFP_HIGHUSER
如同 GFP_USER, 但是从高端内存分配, 如果有. 高端内存在下一个子节描述.
F.GFP_NOFS,GFP_NOIO
这个标志功能如同 GFP_KERNEL, 但是它们增加限制到内核能做的来满足请求. 一个 GFP_NOFS 分配不允许进行任何文件系统调用, 而 GFP_NOIO 根本不允许任何 I/O 初始化. 它们主要地用在文件系统和虚拟内存代码, 那里允许一个分配睡眠, 但是递归的文件系统调用会是一个坏注意.
上面列出的这些分配标志可以是下列标志的相或来作为参数, 这些标志改变这些分配如何进行:
__GFP_DMA
这个标志要求分配在能够 DMA 的内存区. 确切的含义是平台依赖的并且在下面章节来解释.
__GFP_HIGHMEM
这个标志指示分配的内存可以位于高端内存.
__GFP_COLD
正常地, 内存分配器尽力返回\"缓冲热\"的页 -- 可能在处理器缓冲中找到的页. 相反, 这个标志请求一个\"冷\"页, 它在一段时间没被使用. 它对分配页作 DMA 读是有用的, 此时在处理器缓冲中出现是无用的. 一个完整的对如何分配 DMA 缓存的讨论看\"直接内存存取\"一节在第 1 章.
__GFP_NOWARN
这个很少用到的标志阻止内核来发出警告(使用 printk ), 当一个分配无法满足.
__GFP_HIGH
这个标志标识了一个高优先级请求, 它被允许来消耗甚至被内核保留给紧急状况的最后的内存页.
__GFP_REPEAT
__GFP_NOFAIL
__GFP_NORETRY
这些标志修改分配器如何动作, 当它有困难满足一个分配. __GFP_REPEAT 意思是\" 更尽力些尝试\" 通过重复尝试 -- 但是分配可能仍然失败. __GFP_NOFAIL 标志告诉分配器不要失败; 它尽最大努力来满足要求. 使用 __GFP_NOFAIL 是强烈不推荐的; 可能从不会有有效的理由在一个设备驱动中使用它. 最后, __GFP_NORETRY 告知分配器立即放弃如果得不到请求的内存.
Ø   内存区段
     __GFP_DMA和__GFP_HIGHMEM的使用与平台相关,Linux把内存分成3个区段:可用于DMA的内存、常规内存、以及高端内存。X86平台上ISA设备DMA区段是内存的前16MB,而PCI设备无此限制。
内存区后面的机制在 mm/page_alloc.c 中实现, 而内存区的初始化在平台特定的文件中, 常常在 arch 目录树的 mm/init.c。
3.kamlloc的使用方法:
     Linux 处理内存分配通过创建一套固定大小的内存对象池. 分配请求被这样来处理, 进入一个持有足够大的对象的池子并且将整个内存块递交给请求者. 驱动开发者应当记住的一件事情是, 内核只能分配某些预定义的, 固定大小的字节数组.
如果你请求一个任意数量内存, 你可能得到稍微多于你请求的, 至多是 2 倍数量. 同样, 程序员应当记住 kmalloc 能够处理的最小分配是 32 或者 64 字节, 依赖系统的体系所使用的页大小. kmalloc 能够分配的内存块的大小有一个上限. 这个限制随着体系和内核配置选项而变化. 如果你的代码是要完全可移植, 它不能指望可以分配任何大于 128 KB. 如果你需要多于几个 KB, 但是, 有个比 kmalloc 更好的方法来获得内存。在设备驱动程序或者内核模块中动态开辟内存,不是用malloc,而是kmalloc ,vmalloc,或者用get_free_pages直接申请页。释放内存用的是kfree,vfree,或free_pages. kmalloc函数返回的是虚拟地址(线性地址). kmalloc特殊之处在于它分配的内存是物理上连续的,这对于要进行DMA的设备十分重要. 而用vmalloc分配的内存只是线性地址连续,物理地址不一定连续,不能直接用于DMA.
  注意kmalloc最大只能开辟128k-16,16个字节是被页描述符结构占用了。
  内存映射的I/O口,寄存器或者是硬件设备的RAM(如显存)一般占用F0000000以上的地址空间。在驱动程序中不能直接访问,要通过kernel函数vremap获得重新映射以后的地址。
  另外,很多硬件需要一块比较大的连续内存用作DMA传送。这块内存需要一直驻留在内存,不能被交换到文件中去。但是kmalloc最多只能开辟大小为32XPAGE_SIZE的内存,一般的PAGE_SIZE=4kB,也就是128kB的大小的内存。
3.kmalloc和vmalloc的区别
• vmalloc()与 kmalloc()都可用于分配内存
• kmalloc()分配的内存处于3GB~high_memory之 间,这段内核空间与物理内存的映射一一对应
•vmalloc()分配的内存在 VMALLOC_START~4GB之间,这段非连续内 存区映射到物理内存也可能是非连续的
• 在内核空间中调用kmalloc()分配连续物理空间,而调用vmalloc()分配非物理连续空间。
• 把kmalloc()所分配内核空间中的地址称为内核逻辑地址
• 把vmalloc()分配的内核空间中的地址称 为内核虚拟地址
• vmalloc()在分配过程中须更新内核页表
总结:
1.kmalloc和vmalloc分配的是内核的内存,malloc分配的是用户的内存
2.kmalloc保证分配的内存在物理上是连续的, kmalloc()分配的内存在0xBFFFFFFF-0xFFFFFFFF以上的内存中,driver一般是用它来完成对DS的分配,更适合于类似设备驱动的程序来使用;
3.vmalloc保证的是在虚拟地址空间上的连续,vmalloc()则是位于物理地址非连续,虚地址连续区,起始位置由VMALLOL_START来决定,一般作为交换区、模块的分配。
3.kmalloc能分配的大小有限,vmalloc和malloc能分配的大小相对较大(因为vmalloc还可以处理交换空间)。
4.内存只有在要被DMA访问的时候才需要物理上连续,vmalloc比kmalloc要慢
5.vmalloc使用的正确场合是分配一大块,连续的,只在软件中存在的,用于缓冲的内存区域。不能在微处理器之外使用。
6.vmalloc 中调用了 kmalloc (GFP—KERNEL),因此也不能应用于原子上下文。
7.kmalloc和 kfree管理内核段内分配的内存,这是真实地址已知的实际物理内存块。
8.vmalloc对应于vfree,分配连续的虚拟内存,但是物理上不一定连续。
9.kmalloc分配内存是基于slab,因此slab的一些特性包括着色,对齐等都具备,性能较好。物理地址和逻辑地址都是连续的

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Linux中动态内存的分配与回收(heap, buddy system, stab) 的相关文章

  • Spring Boot实践 第二章 Spring boot 的配置文件

    前一章 我们创建了第一个spring boot 程序 这一章分享一下spring boot的配置方式和一些技巧 spring boot 的特性之一就是 配置简单 spring boot不再使用之前spring 的xml配置方式 xml的配置
  • Netty 性能测试(与Tomcat 对比)

    一直以来都认为 Netty 的性能会非常优秀 打算在适当的时候使用它来开发一些要求超高新能的服务 今天兴致勃勃的写了个简单的 HTTP 服务 同样也用 tomcat 写了一个对比的 jsp 页面 结果测试下来 感觉 Netty 的性能提升并
  • 【数据结构】查找算法:二分查找、顺序查找

    08年9月入学 12年7月毕业 结束了我在软件学院愉快丰富的大学生活 此系列是对四年专业课程学习的回顾 索引参见 http blog csdn net xiaowei cqu article details 7747205 查找算法 查找算
  • 企业微信免登录跳转自建应用

    项目场景 企业微信免登录自建H5应用 项目场景 已存在开发好的web程序 现在需要集成到企业应用里 预想的是新建一个企业微信应用 点击后直接免登录进入web程序应用 一 创建企业微信应用 首先 创建企业微信账户并进入管理后台 https w
  • MyBatis快速入门(一) 搭建环境和单表映射

    MyBatis简介 一说起对象关系映射框架 大家第一时间想到的肯定是Hibernate Hibernate作为一个著名的框架 功能十分强大 我们只需要配置好实体类和数据表之间的关系 Hibernate就会自动帮我们完成生成并执行SQL语句
  • hive使用时的用户权限问题

    0 jdbc hive2 node1 10000 gt create role root Error Error while processing statement FAILED Execution Error return code 1
  • 599. Minimum Index Sum of Two Lists

    Suppose Andy and Doris want to choose a restaurant for dinner and they both have a list of favorite restaurants represen
  • Java跨平台原理

    第二部分 Java跨平台原理 1 什么是平台 Java是可以跨平台的编程语言 那我们首先得知道什么是平台 我们把CPU处理器与操作系统的整体叫平台 CPU大家都知道 如果计算机是人 那CPU就是人的大脑 它既负责思维运算 又负责身体各部件的
  • Hadoop003-Hadoop的I/O操作

    1 数据完整性 重点词汇 1 校验和 checksum 2 复本因子 replication factor 3 一系列datanode组成的管线 4 fs checksum 5 distcp 2 压缩 文件压缩优点 1 减少存储文件所需要的
  • django启动服务器失败-已解决

    参考菜鸟教程 启动失败 解决办法 将python3改为python
  • android手机时钟、闹钟、计时器、秒表app源码

    简 介 此多功能闹钟界面采用TabHost框架 头部包含分别用LinearLayout水平布局显示四个标签闹钟 时钟 计时器和秒表 FrameLayout框架内部采用LinearLayout垂直布局 功能事件的基本实现分别有AlarmVie
  • MyBatis+MySQL 返回插入的主键ID

    需求 使用MyBatis往MySQL数据库中插入一条记录后 需要返回该条记录的自增主键值 方法 在mapper中指定keyProperty属性 示例如下 Xml代码
  • Unity里面实现单侧拉伸

    完成部分功能的时候 需要模型单侧拉伸 模型锚点不好修改下 可以通过父子物体的方式来实现修改锚点从而实现单侧拉伸 普通状况下锚点在中间 直接拉伸会从中间往两侧伸展 通过把目标对象挂靠在一个空的GameObject中 再把目标对象的一角对应在空
  • (详细安装python_pcl) python_pcl+windows+anaconda

    需要根据已有的python pcl whl文件的版本来创建对应anaconda虚拟环境的python版本 这里拿python pcl 0 3 0rc1 cp37 cp37m win amd64 whl 文件来举例 可以根据文件名cp37 来
  • 面试逻辑题

    逻辑题目 逻辑题目现在也是面试中常考的题目 也不清楚面试出这种题目的意义 可能就是考察面试人员是否逻辑清晰 这种题目没有什么好的方法 除非你见过原题 否则 只能根据所给出的条件慢慢分析 尽量不要用常规思路 希望大家要跳跃思维 如果实在不行就
  • 二进制安装kubernetes三主三从高可用集群

    本文基于Kubernetes1 19版本 以二进制文件方式对如何配置 部署一个启用了安全机制 3节点高可用的Kubernetes集群进行说明 对于测试环境 可以适当进行简化 将某些组件部署为单点 一 k8s高可用集群架构 在正式的环境中应确
  • 数据库的数据备份和数据恢复MySQL

    一 数据的备份 在未登录MySQL的状态下输入下列代码 格式如下 mysqldump uusername p gt d db sql 例如 我的用户名为root 我将备份文件放到d盘目录下 将文件取名为db sql 需要注意两个地方 1 p
  • TIME_WAIT机理

    注 本文系转载 尊重原作者原文链接 TIME WAIT状态原理 通信双方建立TCP连接后 主动关闭连接的一方就会进入TIME WAIT状态 客户端主动关闭连接时 会发送最后一个ack后 然后会进入TIME WAIT状态 再停留2个MSL时间
  • H5+css+js的商品放大镜效果

  • vCenter Server安装报错:内存或cpu不足

    vCenter Server安装报错 内存或cpu不足 前言 在安装vCenter Server7 0时报错 Not enough memory in target host EXSI7 0安装在VMware workstation里面 配

随机推荐

  • 解决用steam客户端购买游戏验证登录信息失败的方法

    用steam客户端购买游戏或者订阅Mod的时候会弹出 正在验证登录信息 的界面 然后登陆失败 尽管你已经登陆了steam 但是好像没有登陆到steam服务器上 你就算是重新登录 翻墙 使用steamcommunity插件 使用加速器 电脑杀
  • HJ28 素数伴侣【python3】

    题目描述 若两个正整数的和为素数 则这两个正整数称之为 素数伴侣 如2和5 6和13 它们能应用于通信加密 现在密码学会请你设计一个程序 从已有的 N N 为偶数 个正整数中挑选出若干对组成 素数伴侣 挑选方案多种多样 例如有4个正整数 2
  • 重启kibana的脚本

    2019独角兽企业重金招聘Python工程师标准 gt gt gt bin bash echo e 033 31m stop kibana by 5601 Now 033 0m ps ef netstat anp grep 5601 awk
  • 【Java笔记】Java8中数组(引用类型)、String、List、Set之间的相互转换问题

    数组 String List Set之间的相互转换问题 如果觉得对你有帮助 能否点个赞或关个注 以示鼓励笔者呢 博客目录 先点这里 本博主要是相理清楚一些转换的逻辑 顺便总结一下贴出来 这里是把一些可以JDK自带的使用方法写出了 不代表没有
  • 解析js面试题(上)

    注 本篇博客的题目出自于博主 小平果118博客 题目地址 http blog csdn net i10630226 article details 49765737 由于该博客并没有抛出来来答案和解析 我在这里以自己的理解来做一下这些题目
  • MicroBlaze系列教程(3):AXI_TIMER的使用

    文章目录 toc AXI TIMER简介 常用函数 使用示例 参考资料 工程下载 本文是Xilinx MicroBlaze系列教程的第3篇文章 AXI TIMER简介 AXI TIMER支持两路可编程32位计数器 可以配置为中断 捕获 PW
  • LoadRunner下载和安装

    文章目录 一 下载地址 二 安装步骤 三 安装过程中遇到的问题 一 下载地址 官方下载地址 https my microfocus com myproducts 网盘下载地址 https pan baidu com s 1hiGC9FjfK
  • cudnn下载与安装

    cudnn的安装 cudnn的安装非常简单 1 下载安装文件 按需求下载cudnn的安装文件 https developer nvidia com rdp cudnn archive 需要注册账号 2 安装cudnn 解压下载的文件 可以看
  • 搭建完整的arm-linux-gcc等交叉编译环境

    搭建完整的arm linux gcc等交叉编译环境 链接 https www cnblogs com uestc mm p 6656325 html 安装环境 Linux版本 Ubuntu 12 04 内核版本 Linux 3 5 0 交叉
  • Android AutoLayout集成使用

    转载自楊帥简书 https www jianshu com p da5d5d4d0901 由于Android屏幕尺寸众多的情况 Android适配一直是个问题 谷歌推出了百分比布局 本人有使用 但是百分比布局在部分时候适配并不是那么完美 偶
  • docker(六)数据挂载之数据卷

    docker容器运行时 是有一个可写入层的 如果我们把容器运行时的数据写在可写入层 会有以下问题 当容器停止运行时 写入的数据会丢失 你也很难将这些数据从容器中取出来给另外的应用程序使用 容器的可写入层与宿主机是紧密耦合的 这些写入的数据在
  • 指针的进阶【下篇】

    文章目录 8 指向函数指针数组的指针 9 回调函数 8 指向函数指针数组的指针 请看代码与注释 int Add int x int y return x y int Sub int x int y return x y int main i
  • Ubuntu22.04.1 Server版本 配置C++开发环境----笔记

    远程ssh 没记错在安装 server版的时候是可以选的 如果没有就执行安装命令 sudo install openssh server y 下载完成后配置端口22 vim etc ssh ssh config 重启ssh sudo ser
  • 利用回调获取自拟定Dialog的返回值

    这里要讲的是如何利用回调获取自拟定DiaLog的返回值 首先看下问题的背景 我们经常会用到Dialog 系统提供了一些常用的Dialog 可以参考这篇博客 点击打开链接 那其中一个常用Dialog做讲解 span style font si
  • java实现进程管理,Java调用批处理或可执行文件和Runtime、Process类实现Java版进程管理器...

    Java调用批处理或可执行文件 用Java编写应用时 有时需要在程序中调用另一个现成的可执行程序或系统命令 这时可以通过组合使用Java提供的Runtime类和Process类的方法实现 下面是一种比较典型的程序模式 Process pro
  • 大数据时代如何保护数据安全?

    当前 大数据正在成为信息时代的核心战略资源 对国家治理能力 经济运行机制 社会生活方式产生了深刻影响 与此同时 各项应用技术背后的数据安全风险也日益凸显 近年来 有关数据泄露 数据窃听 数据滥用等安全事件屡见不鲜 保护数据资产已引起各国高度
  • JS/CSS 实现鼠标移动更改列表奇偶行背景色

    需求 鼠标移动到一个列表时 奇数行显示一种背景色 偶数行显示另一种背景色 鼠标移出时 背景色复原 实现效果 代码实现 CSS JS
  • matlab正激变换器,12个步骤设计恒流正激式开关电源

    原标题 12个步骤设计恒流正激式开关电源 摘要 1 电源技术要求 2 设计步骤 3 变压器设计 4 输出滤波器设计 5 复位电路计算 6 功率开关管选择 7 输出二极管选择 8 恒流输出电路设计 9 缓冲吸收电路设计 10 控制电路设计 1
  • 华为ensp安装包及安装教程(详细版)

    今天给小伙伴们详细介绍一下ensp的安装教程 附有安装包有 可自行下载 目录 一 安装包链接 二 安装详细步骤 1 安装Oracle VM VirtualBox 2 安装Wireshark 3 安装ensp 4 安装完成 三 总结 一 安装
  • Linux中动态内存的分配与回收(heap, buddy system, stab)

    1 malloc 和free的原理 http m blog csdn net article details id 39496057 从操作系统角度来看 进程分配内存有两种方式 分别由两个系统调用完成 brk和mmap 不考虑共享内存 1