Chinaunix首页 | 论坛 | 博客
  • 博客访问: 3514903
  • 博文数量: 1805
  • 博客积分: 135
  • 博客等级: 入伍新兵
  • 技术积分: 3345
  • 用 户 组: 普通用户
  • 注册时间: 2010-03-19 20:01
文章分类

全部博文(1805)

文章存档

2017年(19)

2016年(80)

2015年(341)

2014年(438)

2013年(349)

2012年(332)

2011年(248)

分类: LINUX

2013-07-07 18:46:30

原文地址:ldd 8 内存分配 作者:heis07w

1. kmalloc

点击(此处)折叠或打开

  1. #include <linux/slab.h>
  2. void *kmalloc(size_t size, int flags);

kmalloc分配的物理内存也是连续的。
常用标志是GFP_KERNEL,表示是进程分配的内存;GFP_ATOMIC表示在原子操作中分配的内存,如中断、tasklet、内核定时器。

内核将内存分为三个区段,为DMA、常规内存、高端内存。kmalloc不可以分配高端内存。

size参数指定的不一定就是正好分配的大小。因为实际分配过程是从对象池中取的,固定大小的内存(类似vector)。大小最小为32、64,最大最好不大于128K。

2. slab
用于频繁分配大小相等的结构所需要的内存。kmem_cache_t
---->创建slab:

点击(此处)折叠或打开

  1. kmem_cache_t *kmem_cache_create(const char *name, size_t size,
  2.  size_t offset,
  3.  unsigned long flags,
  4.  void (*constructor)(void *, kmem_cache_t *,
  5.  unsigned long flags), void (*destructor)(void *, kmem_cache_t *, unsigned long flags));
其中可指定构造、析构函数。

---->从创建的slab中分配对象:

点击(此处)折叠或打开

  1. void *kmem_cache_alloc(kmem_cache_t *cache, int flags);
返回的指针即为对象指针,这个flags与传给kmalloc的相同。

---->释放内存对象回slab

点击(此处)折叠或打开

  1. void kmem_cache_free(kmem_cache_t *cache, const void *obj);

---->释放slab
点击(此处)折叠或打开
  1. int kmem_cache_destroy(kmem_cache_t *cache);

使用slab的另一个好处是可以统计调整缓存的使用情况:/proc/slabinfo。


3. 内存池
有时内存分配必须成功,所以这个内存池就是应对这种情况。它其实是某种形式的slab,但是是预先分配的。
mempool很容易浪费内存,不推荐使用。

4.get_free_page相关
用于分配大块内存的情况。分配的结果是连续的物理页。
优点在于不会产生内存碎片,页面也完全属于分配者。

5. alloc_pages
用于直接返回page结构。尤其在高端内存中使用。

6. vmalloc
分配虚拟地址连续,但物理上不连续的区域。

缺点:
虽然和kmalloc与__get_free_page一样返回的是虚拟地址,但是它是需要修改页表的。导致使用效率不高;
它不可在原子上下文中使用,因为内部调用了kmalloc(GFP_KERNEL)可能导致睡眠。
优点:
分配大页时,get_free_pages慢,因为它要等连续的物理内存,vmalloc快一些。

应该尽可能避免使用。


7.超大内存区分配
唯一、粗暴的方式是在系统引导时,保留私有的内存池实现。因为引导时内核可以访问所有的物理内存。


阅读(460) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~