30天自制操作系统-第9天 harib06d 图解内存释放

其实还是比较简单的,只是纯代码可能不好理解,加上图片就好理解了

情况1(左部合并)

在这里插入图片描述

要释放的内存块(绿色内存区域)左边是空闲的,就将它和左边合并,由于没有内存块数量的变化,就不需要移动内存块,对应的代码部分如下

	if (i > 0) {
		/* 前がある */
		if (man->free[i - 1].addr + man->free[i - 1].size == addr) {
			/* 前のあき領域にまとめられる */
			man->free[i - 1].size += size;

情况2(左右合并)

只考虑到上面的左部合并是不够的,当左右都有空闲内存块的时候,先合并到左部Free[i-1],再将Free[i]合并到新的Free[i-1],但是由于内存块数量减少了,移动内存块,这里旧的Free[i]被合并了,就需要将空闲内存块的数量-1(对应代码中的man->frees–),除此之外,还需要将之后的Free[i+1]复制到Free[i],同理Free[i+2]复制到Free[i+1],.(递归复制下去)…,复制完最后一块的时候,

在这里插入图片描述

代码如下

	if (i > 0) {
		/* 前がある */
		if (man->free[i - 1].addr + man->free[i - 1].size == addr) {
			/* 前のあき領域にまとめられる */
			man->free[i - 1].size += size;
			if (i < man->frees) {
				/* 後ろもある */
				if (addr + size == man->free[i].addr) {
					/* なんと後ろともまとめられる */
					man->free[i - 1].size += man->free[i].size;
					/* man->free[i]の削除 */
					/* free[i]がなくなったので前へつめる */
					man->frees--;
					for (; i < man->frees; i++) {
						man->free[i] = man->free[i + 1]; /* 構造体の代入 */
					}
				}
			}
			return 0; /* 成功終了 */
		}
	}

情况3(右部合并)

如果不是上面的情况,即Free[i-1]不在释放的内存块左侧,空闲内存块Free[i]恰好在右侧,就将内存块合并到右侧Free[i],由于没有内存块数量变化,依旧不用移动内存块。

在这里插入图片描述

代码如下

	/* 前とはまとめられなかった */
	if (i < man->frees) {
		/* 後ろがある */
		if (addr + size == man->free[i].addr) {
			/* 後ろとはまとめられる */
			man->free[i].addr = addr;
			man->free[i].size += size;
			return 0; /* 成功終了 */
		}
	}

情况4(新建内存块)

如果不是上面的情况,即Free[i-1]不在释放的内存块左侧,Free[i]也不在该内存块右侧,就只能新建一个内存块,由于内存块数量改变,需要移动内存块。
首先我们需要考虑一件事,这个新建的内存块放在哪里?
因为Free[i-1]及之前都不能移动,所以只好对Free[i]及其之后下手了。
所以先而从末尾**Free[man->frees]**开始(这是空白的,因为数组是从0开始的,man->frees只表示空闲数量,所以Free[man->frees-1]才是第man->frees个有实际信息的元素),复制Free[man->frees-1]的内容到Free[man->frees],递归下去直到Free[i]复制到Free[i+1]的内容,将空闲内存块数量+1(man->frees++),,然后将Free[i]设置为刚刚释放的内存块(绿色部分)。

在这里插入图片描述

	/* 前にも後ろにもまとめられない */
	if (man->frees < MEMMAN_FREES) {
		/* free[i]より後ろを、後ろへずらして、すきまを作る */
		for (j = man->frees; j > i; j--) {
			man->free[j] = man->free[j - 1];
		}
		man->frees++;
		if (man->maxfrees < man->frees) {
			man->maxfrees = man->frees; /* 最大値を更新 */
		}
		man->free[i].addr = addr;
		man->free[i].size = size;
		return 0; /* 成功終了 */
	}

情况5(超过最大空闲块数量)

由于数组Free的最大长度有限,最大空闲块数量也有限,被设置为MEMMAN_FREES=4090

#define MEMMAN_FREES		4090	/* これで約32KB */

对应结构体

struct MEMMAN {		/* メモリ管理 */
	int frees, maxfrees, lostsize, losts;
	struct FREEINFO free[MEMMAN_FREES];
};

超过的部分将会被记录到内存丢失信息中

	/* 後ろにずらせなかった */
	man->losts++;
	man->lostsize += size;
	return -1; /* 失敗終了 */
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值