s081[2]-unix内存分配方式-malloc实现

本文深入探讨Unix系统中的内存分配机制,重点介绍了K&R malloc、region-based allocator和buddy allocator三种实现方式。内容包括内存分配的目标、系统接口如sbrk和mmap的使用,以及各种内存分配策略的优缺点。通过对这些基础知识的学习,读者可以更好地理解内存管理在系统编程中的关键作用。
摘要由CSDN通过智能技术生成

内存分配

前序课程

操作系统接口:https://dreamerjonson.com/2020/01/04/6-s081-1/

系统编程(Systems programming)

wiki参考

  • 与应用程序编程相比,系统编程的主要区别在于,应用程序编程旨在产生直接向用户提供服务的软件。
  • 系统编程主要为其他应用程序提供服务,直接操作操作系统。它的目标是实现对可用资源的有效利用。

例如:

  • unix utilities
  • K/V servers
  • ssh
  • bigint library

挑战:

  • 低级编程环境
    • 数字是64位(不是无限的整数)
    • 分配/释放内存
    • 并发
      • 允许并行处理请求
  • 崩溃
  • 性能
  • 为应用程序提供硬件支持

动态内存分配是一项基本的系统服务

  • 底层编程: 指针操作,类型转换
  • 使用底层操作系统请求内存块(memory chunks)
  • 性能非常重要
  • 支持广泛类型的应用程序负载

应用程序结构

  • text

  • data (静态存储)

  • stack (栈存储)

  • heap (动态内存分配)
    使用 sbrk() o或 mmap() 操作系统接口扩展堆。
    [text | data | heap -> … <- stack]
    0 top of address space

  • data段的内存分配是静态的,始终存在。

  • 栈的分配在函数中,随着函数消亡而释放。

  • 堆的分配与释放,调用接口:
    — malloc(int sz)
    — free§

堆分配的目标

  • 快速分配和释放
  • 内存开销小
  • 想要使用所有内存
  • 避免碎片化

下面介绍几种malloc实现的方式

方式1:K&R malloc

又叫做first-fit规则, 即查找第一个可用的匹配块。与之相对应的是查找第一个最符合(best-fit)的可用块。
K&R malloc的实现来自书籍 the C programming language by Kernighan and Ritchie (K&R) Section 8.7

维持一个链表

维持的free list是一个环。 第一个元素是base。

#define NALLOC  1024  /* minimum #units to request */

struct header {
  struct header *ptr;
  size_t size;
};

typedef struct header Header;

static Header base;
static Header *freep = NULL;

内存分配

指定分配的内存大小为sizeof(Header)的倍数,且一定大于nbytes。nunits就是这个倍数。

  • 循环free list。 找到第一个符合即大于等于nbytes的块。
    — 如果刚好合适,则链表删除此块并返回此块。
    — 如果大于,则截断此元素
    — 如果没有找到合适的块,则调用moreheap新分配一个。
/* malloc: general-purpose storage allocator */
void *
kr_malloc(size_t nbytes)
{
  Header *p, *prevp;
  unsigned nunits;

  nunits = (nbytes + sizeof(Header) - 1) / sizeof(Header) + 1;
  // base作为第一个元素。
  if ((prevp = freep) == NULL) {	/* no free list yet */
    base.ptr = freep = prevp = &base;
    base.size = 0;
  }

  for (p = prevp->ptr; ; prevp = p, p = p->ptr) {
    if (p->size >= nunits) {	/* big enough */
      if (p->size == nunits)	/* exactly */
	prevp->ptr = p->ptr;
      else {	/* allocate tail end */
	p->size -= nunits;
	p += p->size;
	p->size = nunits;
      }
      freep 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值