权力的权力游戏第7季百度云七季第5集百度云

C/C++(69)
伙伴关系也好、slab技术也好,从内存管理理论角度而言目的基本是一致的,它们都是为了防止“分片”,不过分片又分为外部分片和内部分片之说,所谓内部分片是说系统为了满足一小段内存区(连续)的需要,不得不分配了一大区域连续内存给它,从而造成了空间浪费;外部分片是指系统虽有足够的内存,但却是分散的碎片,无法满足对大块“ 连续内存”的需求。无论何种分片都是系统有效利用内存的障碍。slab分配器使得一个页面内包含的众多小块内存可独立被分配使用,避免了内部分片,节约了空闲内存。伙伴关系把内存块按大小分组管理,一定程度上减轻了外部分片的危害,因为页框分配不在盲目,而是按照大小依次有序进行,不过伙伴关系只是减轻了外部分片,但并未彻底消除。你自己比划一下多次分配页面后,空闲内存的剩余情况吧。
所以避免外部分片的最终思路还是落到了如何利用不连续的内存块组合成“看起来很大的内存块”——这里的情况很类似于用户空间分配虚拟内存,内存逻辑上连续,其实映射到并不一定连续的物理内存上。Linux内核借用了这个技术,允许内核程序在内核地址空间中分配虚拟地址,同样也利用页表(内核页表)将虚拟地址映射到分散的内存页上。以此完美地解决了内核内存使用中的外部分片问题。内核提供vmalloc函数分配内核虚拟内存,该函数不同于kmalloc,它可以分配较Kmalloc大得多的内存空间(可远大于128K,但必须是页大小的倍数),但相比Kmalloc来说,Vmalloc需要对内核虚拟地址进行重映射,必须更新内核页表,因此分配效率上要低一些(用空间换时间)
与用户进程相似,内核也有一个名为init_mm的mm_strcut结构来描述内核地址空间,其中页表项pdg=swapper_pg_dir包含了系统内核空间(3G-4G)的映射关系。因此vmalloc分配内核虚拟地址必须更新内核页表,而kmalloc或get_free_page由于分配的连续内存,所以不需要更新内核页表。
vmalloc分配的内核虚拟内存与kmalloc/get_free_page分配的内核虚拟内存位于不同的区间,不会重叠。因为内核虚拟空间被分区管理,各司其职。进程空间地址分布从0到3G(其实是到PAGE_OFFSET, 在0x86中它等于0xC0000000),从3G到vmalloc_start这段地址是物理内存映射区域(该区域中包含了内核镜像、物理页面表mem_map等等)比如我使用的系统内存是64M(可以用free看到),那么(3G——3G+64M)这片内存就应该映射到物理内存,而vmalloc_start位置应在3G+64M附近(说&附近&因为是在物理内存映射区与vmalloc_start期间还会存在一个8M大小的gap来防止跃界),vmalloc_end的位置接近4G(说&接近&是因为最后位置系统会保留一片128k大小的区域用于专用页面映射,还有可能会有高端内存映射区,这些都是细节,这里我们不做纠缠)。
上图是内存分布的模糊轮廓
 & 由get_free_page或Kmalloc函数所分配的连续内存都陷于物理映射区域,所以它们返回的内核虚拟地址和实际物理地址仅仅是相差一个偏移量(PAGE_OFFSET),你可以很方便的将其转化为物理内存地址,同时内核也提供了virt_to_phys()函数将内核虚拟空间中的物理映射区地址转化为物理地址。要知道,物理内存映射区中的地址与内核页表是有序对应的,系统中的每个物理页面都可以找到它对应的内核虚拟地址(在物理内存映射区中的)。
而vmalloc分配的地址则限于vmalloc_start与vmalloc_end之间。每一块vmalloc分配的内核虚拟内存都对应一个vm_struct结构体(可别和vm_area_struct搞混,那可是进程虚拟内存区域的结构),不同的内核虚拟地址被4k大小的空闲区间隔,以防止越界——见下图)。与进程虚拟地址的特性一样,这些虚拟地址与物理内存没有简单的位移关系,必须通过内核页表才可转换为物理地址或物理页。它们有可能尚未被映射,在发生缺页时才真正分配物理页面。
这里给出一个小程序帮助大家认清上面几种分配函数所对应的区域。
#include&linux/module.h&
#include&linux/slab.h&
#include&linux/vmalloc.h&
unsigned char *
unsigned char *
unsigned char *
int init_module(void)
&pagemem = get_free_page(0);
&printk(&&1&pagemem=%s&,pagemem);
&kmallocmem = kmalloc(100,0);
&printk(&&1&kmallocmem=%s&,kmallocmem);
&vmallocmem = vmalloc(1000000);
&printk(&&1&vmallocmem=%s&,vmallocmem);
void cleanup_module(void)
&free_page(pagemem);
&kfree(kmallocmem);
&vfree(vmallocmem);
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:282445次
积分:3770
积分:3770
排名:第6692名
转载:565篇
(5)(11)(31)(1)(13)(14)(1)(27)(16)(14)(3)(46)(29)(35)(23)(58)(9)(7)(34)(2)(8)(6)(1)(2)(2)(28)(33)(71)(39)(2)1.malloc 和free的原理(http://m.blog.csdn.net/article/details?id=)
从操作系统角度来看,进程分配内存有两种方式,分别由两个系统调用完成: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进行内存分配和释放,有以下弊端:
调用malloc/new,系统需要根据“最先匹配”、“最优匹配”或其他算法在内存空闲块表中查找一块空闲内存,调用free/delete,系统可能需要合并空闲内存块,这些会产生额外开销
频繁使用时会产生大量内存碎片,从而降低程序运行效率容易造成内存泄漏
内存池(memory pool)是代替直接调用malloc/free、new/delete进行内存管理的常用方法,当我们申请内存空间时,首先到我们的内存池中查找合适的内存块,而不是直接向操作系统申请,优势在于:
比malloc/free进行内存申请/释放的方式快不会产生或很少产生堆碎片可避免内存泄漏
在启动的时候,一个”内存池”(Memory
Pool)分配一块很大的内存,并将会将这个大块(block)分成较小的块(smaller
chunks)。每次你从内存池申请内存空间时,它会从先前已经分配的块(chunks)中得到,而不是从操作系统。
http://blog.csdn.net/shawngucas/article/details/6574863
在设备驱动程序或者内核模块中动态开辟内存,不是用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内核中引入了伙伴系统算法(buddy system)把所有的空闲页框分组为11个 块链表,每个块链表分别包含大小为1,2,4,8,16,32,64,128,256,512和1024个连续页框的页框块最大可以申请1024个连
续页框,对应4MB大小的连续内存每个页框块的第一个页框的物理地址是该块大小的整数倍
  假设要申请一个256个页框的块,先从256个页框的链表中查找空闲块,如果没有,就去512个 页框的链表中找,找到了则将页框块分为2个256个 页框的块,一个分配给应用,另外一个移到256个页框的链表中如果512个页框的链表中仍没有空闲块,继续向1024个页
框的链表查找,如果仍然没有,则返回错误
  页框块在释放时,会主动将两个连续的页框块合并为一个较大的页框块
  1.2.slab分 配器
  slab分配器源于 Solaris 2.4 的 分配算法,工作于物理内存页框分配器之上,管理特定大小对象的缓存,进行快速而高效的内存分配
  slab分配器为每种使用的内核对象建立单独的缓冲区Linux 内核已经采用了伙伴系统管理物理内存页框,因此 slab分配器直接工作于伙伴系 统之上每种缓冲区由多个
slab 组成,每个 slab就是一组连续的物理内存页框,被划分成了固定数目的对象根据对象大小的不同,缺省情况下一个 slab 最多可以由 1024个页框构成出于对齐
等其它方面的要求,slab 中分配给对象的内存可能大于用户要求的对象实际大小,这会造成一定的 内存浪费
  2.常用内存分配函数
  2.1.__get_free_pages
  unsigned long __get_free_pages(gfp_t gfp_mask, unsigned int order)
  __get_free_pages函数是最原始的内存分配方式,直接从伙伴系统中获取原始页框,返回值为第一个页框的起始地址__get_free_pages在实现上只是封装了alloc_pages函 数,从代码分析,alloc_pages函数会分配长度为1&&order的
连续页框块order参数的最大值由include/Linux/Mmzone.h文 件中的MAX_ORDER宏决定,在默认的2.6.18内 核版本中,该宏定义为10也就是说在理论上__get_free_pages函
数一次最多能申请1&&10 * 4KB也就是4MB的 连续物理内存但是在实际应用中,很可能因为不存在这么大量的连续空闲页框而导致分配失败在中,order为10时分配成功,order为11则返回错误
  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分配器的一种内存分配方式,适用于反复分配释放同一大小内存块的场合首先用kmem_cache_create创建一个高速缓存区域,然后用kmem_cache_alloc从
该高速缓存区域中获取新的内存块&kmem_cache_alloc一次能分配的最大内存由mm/slab.c文件中的MAX_OBJ_ORDER宏 定义,在默认的2.6.18内核版本中,该宏定义为5, 于是一次最多能申请1&&5 *
4KB也就是128KB的 连续物理内存分析内核源码发现,kmem_cache_create函数的size参数大于128KB时会调用BUG()结果验证了分析结果,用kmem_cache_create分
配超过128KB的内存时使内核崩溃
  2.3.kmalloc
  void *kmalloc(size_t size, gfp_t flags)
  kmalloc是内核中最常用的一种内存分配方式,它通过调用kmem_cache_alloc函 数来实现kmalloc一次最多能申请的内存大小由include/Linux/Kmalloc_size.h的 内容来决定,在默认的2.6.18内核版本中,kmalloc一
次最多能申请大小为131702B也就是128KB字 节的连续物理内存测试结果表明,如果试图用kmalloc函数分配大于128KB的内存,编译不能通过
  2.4.vmalloc
  void *vmalloc(unsigned long size)
  前面几种内存分配方式都是物理连续的,能保证较低的平均访问时间但是在某些场合中,对内存区的请求不是很频繁,较高的内存访问时间也 可以接受,这是就可以分配一段线性连续,物理不连续的地址,带来的好处是一次可以分配较大块的内存图3-1表
示的是vmalloc分配的内存使用的地址范围vmalloc对 一次能分配的内存大小没有明确限制出于性能考虑,应谨慎使用vmalloc函数在测试过程中,
最大能一次分配1GB的空间
  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机制能大幅提高与设备通信的 吞吐量DMA操作中,涉及到CPU高速缓 存和对应的内存数据一致性的问题,必须保证两者的数据一致,在x86_64体系结构中,硬件已经很
好的解决了这个问题, dma_alloc_coherent和__get_free_pages函数实现差别不大,前者实际是调用__alloc_pages函 数来分配内存,因此一次分配内存的大小限制和后者一样__get_free_pages分配的内
存同样可以用于DMA操作测试结果证明,dma_alloc_coherent函 数一次能分配的最大内存也为4M
  2.6.ioremap
  void * ioremap (unsigned long offset, unsigned long size)
  ioremap是一种更直接的内存“分配”方式,使用时直接指定物理起始地址和需要分配内存的大小,然后将该段 物理地址映射到内核地址空间ioremap用到的物理地址空间都是事先确定的,和上面的几种内存 分配方式并不太一样,并不是分配一段新的物理内存ioremap多用于设备驱动,可以让CPU直接访问外部设备的IO空间ioremap能映射的内存由原有的物理内存空间决定,所以没有进行测试
  2.7.Boot Memory
  如果要分配大量的连续物理内存,上述的分配函数都不能满足,就只能用比较特殊的方式,在Linux内 核引导阶段来预留部分内存
  2.7.1.在内核引导时分配内存
  void* alloc_bootmem(unsigned long size)
  可以在Linux内核引导过程中绕过伙伴系统来分配大块内存使用方法是在Linux内核引导时,调用mem_init函数之前 用alloc_bootmem函数申请指定大小的内存如果需要在其他地方调用这块内存,可以将alloc_bootmem返回的内存首地址通过EXPORT_SYMBOL导
出,然后就可以使用这块内存了这种内存分配方式的缺点是,申请内存的代码必须在链接到内核中的代码里才能使用,因此必须重新编译内核,而且内存管理系统 看不到这部分内存,需要用户自行管理测试结果表明,重新编译内核后重启,能够访问引导时分配的内存块
  2.7.2.通过内核引导参数预留顶部内存
  在Linux内核引导时,传入参数“mem=size”保留顶部的内存区间比如系统有256MB内 存,参数“mem=248M”会预留顶部的8MB内存,进入系统后可以调用ioremap(0xFx800000)来申请这段内存
  3.几种分配函数的比较
& &kmalloc内存分配和malloc相似,除非被阻塞否则他执行的速度非常快,而且不对获得空间清零.
说明:在用kmalloc申请函数后,要清零用memset()函数对申请的内存进行清零。
2.kamlloc函数原型:
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 初始化. 它们主要地用在文件系统和虚拟内存代码, 那里允许一个分配睡眠, 但是递归的文件系统调用会是一个坏注意.
上面列出的这些分配标志可以是下列标志的相或来作为参数, 这些标志改变这些分配如何进行:
这个标志要求分配在能够 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的区别
o vmalloc()与 kmalloc()都可用于分配内存
o kmalloc()分配的内存处于3GB~high_memory之 间,这段内核空间与物理内存的映射一一对应
ovmalloc()分配的内存在 VMALLOC_START~4GB之间,这段非连续内 存区映射到物理内存也可能是非连续的
o 在内核空间中调用kmalloc()分配连续物理空间,而调用vmalloc()分配非物理连续空间。
o 把kmalloc()所分配内核空间中的地址称为内核逻辑地址
o 把vmalloc()分配的内核空间中的地址称 为内核虚拟地址
o 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的一些特性包括着色,对齐等都具备,性能较好。物理地址和逻辑地址都是连续的
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:4197次
排名:千里之外
原创:39篇
转载:10篇
(9)(14)(7)(5)(2)(1)(2)(4)(5)君,已阅读到文档的结尾了呢~~
[]LINUX存储管理第二章 linux存储管理linux的分页管理机制linux的地址划分o 每一个用户进程都可以访问4gb的线性虚拟内存空间。 o 从0到3gb的虚拟内存地址是用户空间,用户进程可以直 接对其进行访问。 o 从3gb到4gb的虚拟内存地址为核心态空间,存放仅供核 心态访问的代码和数据,用户态进程不可访问。 o 所有..
扫扫二维码,随身浏览文档
手机或平板扫扫即可继续访问
[]LINUX存储管理
举报该文档为侵权文档。
举报该文档含有违规或不良信息。
反馈该文档无法正常浏览。
举报该文档为重复文档。
推荐理由:
将文档分享至:
分享完整地址
文档地址:
粘贴到BBS或博客
flash地址:
支持嵌入FLASH地址的网站使用
html代码:
&embed src='/DocinViewer-4.swf' width='100%' height='600' type=application/x-shockwave-flash ALLOWFULLSCREEN='true' ALLOWSCRIPTACCESS='always'&&/embed&
450px*300px480px*400px650px*490px
支持嵌入HTML代码的网站使用
您的内容已经提交成功
您所提交的内容需要审核后才能发布,请您等待!
3秒自动关闭窗口

我要回帖

更多关于 权力的游戏6季百度云 的文章

 

随机推荐