lcc之内存分配
现在感觉这本书有些地方没有说透,如果自己的理解能力与基础知识够强的话,理解起来还好,如果不行的话,某些地方理解起来会相当的头疼。
现在来说说内存管理。当初看这一章的时候很快就过去了,感觉很多地方很好理解,当看到后面看不下去时,从头再仔细看时,发现当时很多没有注意到的细节问题。
在该书中图2-1我一直觉得这个图画错了,最后发现是我想当然了,其实这个图很正确,只是我没有理解正确。
文中把内存分成了三个大块。
这first仅仅表示这三块的头,即开始的地方, static struct block first[] = { { NULL }, { NULL }, { NULL } }, 每一个大块有若干block连接起来
static struct block *arena[] = { &first[0], &first[1], &first[2] }; arena代表每个大块的尾部,从头到尾中间的任何一块即使有空闲空间也不使用,这些空间被浪费了。
在上面的初始化中arena指向first中的各个项。
具体情况详见图2-1,其中另外一点需要注意的是f每一大块的第一个block中的avail和limit都是NULL表示头指针。
下面解释下allocate()函数。
简要说下步骤,首先从freeblock中开始找,freeblock是共享的,三个大块都可以从中来获取可分配的block,如果在freeblock中没有找到足够大小的block,于是就分配一个新的block,如果找到了足够大的block,则用该block。
void *allocate(n, a) unsigned long n; unsigned a; {
struct block *ap;
assert(a < NELEMS(arena));
assert(n > 0);
ap = arena[a];//此时ap指向大块a中的最后一个block
n = roundup(n, sizeof (union align));
//下面这段循环好阴险,先从freeblock中找,找不到再分配,感觉写的不太好,如果把else移出来就好理解多了
while (n > ap->limit - ap->avail)
{
//这里的freeblock是共享的,三个大的块共写freeblock。
if ((ap->next = freeblocks) != NULL)
{
freeblocks = freeblocks->next;
ap = ap->next;//指向freeblock中的block
}
else
{
unsigned m = sizeof (union header) + n + 10*1024;
ap->next = malloc(m);//malloc return a address of the memory
ap = ap->next;
if (ap == NULL)
{
error("insufficient memory\n");
exit(1);
}
ap->limit = (char *)ap + m;
}
//经过上面的if和else已经得到了满足大小的内存block(不论是从freeblock中分配得到的还是新分配的)
ap->avail = (char *)((union header *)ap + 1);
ap->next = NULL;
arena[a] = ap;
}
ap->avail += n;
return ap->avail - n;
}
上面还有一个疑问,first代表头,arena代表尾,当分配一个block时,是怎么把若干block通过next联系起来的。
lcc之内存分配的更多相关文章
- java\c程序的内存分配
JAVA 文件编译执行与虚拟机(JVM)介绍 Java 虚拟机(JVM)是可运行Java代码的假想计算机.只要根据JVM规格描述将解释器移植到特定的计算机上,就能保证经过编译的任何Java代码能够在该 ...
- java程序的内存分配
java程序的内存分配 JAVA 文件编译执行与虚拟机(JVM)介绍 Java 虚拟机(JVM)是可运行Java代码的假想计算机.只要根据JVM规格描述将解释器移植到特定的计算机上,就能保证经过编译的 ...
- java程序的内存分配(一)
首 页 阅览室 馆友 我的图书馆 帐号 java程序的内存分配(一) 收藏 JAVA 文件编译执行与虚拟机(JVM)介绍 Java 虚拟机(JVM)是可运行Java代码的假想计算机.只要根据J ...
- 《深入理解Java虚拟机》内存分配策略
上节学习回顾 1.判断对象存活算法:引用计数法和可行性分析算法 2.垃圾收集算法:标记-清除算法.复制算法.标记-整理算法 3.垃圾收集器: Serial:新生代收集器,采用复制算法,单线程. Par ...
- Java的内存分配
java内存分配 A:栈 存储局部变量 B:堆 存储所有new出来的 C:方法区(方法区的内存中) 类加载时 方法信息保存在一块称为方法区的内存中, 并不随你创建对象而随对象保存于堆中; D:本地方法 ...
- C语言内存分配方法。
当C程序运行在操作系统上时,操作系统会给每一个程序分配一定的栈空间. 堆为所有程序共有的,需要时需要申请访问. 一.栈 局部变量.函数一般在栈空间中. 运行时自动分配&自动回收:栈是自动管理的 ...
- JVM内存分配策略
在 JVM内存垃圾回收方法 中,我们已经详细讨论了内存回收,但是,我们程序中生成的对象是如何进行分配的呢?以下所述针对的是HotSpot虚拟机. 1.Java堆结构 以HotSpot为例,如下图: H ...
- Java的垃圾回收和内存分配策略
本文是<深入理解Java虚拟机 JVM高级特性与最佳实践>的读书笔记 在介绍Java的垃圾回收方法之前,我们先来了解一下Java虚拟机在执行Java程序的过程中把它管理的内存划分为若干个不 ...
- Buddy内存分配算法
Buddy(伙伴的定义): 这里给出伙伴的概念,满足以下三个条件的称为伙伴:1)两个块大小相同:2)两个块地址连续:3)两个块必须是同一个大块中分离出来的: Buddy算法的优缺点: 1)尽管伙伴内存 ...
随机推荐
- VS2010中配置C#Project不生成.vhost.exe和.pdb文件的方法
在VS2010中编译C#工程时,在C#的Project的属性界面的Build选项卡中当Configuration : Relese 时,依然会生成扩展名为.vhost.exe和.pdb文件. 其中.p ...
- [Unity3d]定义自己的鼠标
[Unity3d]自己定义鼠标 我们在用unity3d开发自己的游戏的时候.自己定义游戏中的鼠标也是常常要用到的.那我就得学学.事实上原理非常easy,先将鼠标给隐藏,然后在鼠标的位置上画出一个自己定 ...
- JAVA中的super和this关键字的使用
一 this关键字 this关键字可以出现在构造方法和实例方法中,不能出现在静态方法中,这是因为静态方法可以用类名来调用,这时可能还没有任何对象诞生. this主要有两种用法: 1 用在构造方法中,调 ...
- HihoCoder——Trie树
本文出自:http://blog.csdn.net/svitter 原题:http://hihocoder.com/contest/hiho2/problem/1 题解:使用Trie树..基础题目.一 ...
- SQL Server错误代码及解释(留着备用)
原文:SQL Server错误代码及解释(留着备用) 转自:http://www.ajia.me/Article/193.html Code Error Message 0 操作成功完成. 1 功能 ...
- Linux磁盘分区,目录树,文件系统的关系(转)
研究了很久,自始至终不能够从三者的区别和联系中找到一个大脑与这些概念之间合适的相处方式.对于基本概念和理论理解不到位,在工作之中会走很多弯路和犯很多错误.今天花一天的时间,终于对三者的区别和联系有了更 ...
- A*寻路算法lua实现
前言:并在相当长的时间没有写blog该,我觉得有点"颓废"该,最近认识到各种同行,也刚刚大学毕业,我认为他们是优秀的.认识到与自己的间隙,有点自愧不如.我没有写blog当然,部分原 ...
- 【C++知识汇总】运营商 & 运算符重载
[运算符] 在进行运算时,假设右括号的话我们知道先运算哪个,那假设没有括号了.算术运算符,关系运算符,逻辑运算符,位运算符.赋值运算符,++.--运算符等等,那么多的运算符.我们先算哪边 ...
- SVN与eclipse整合和利用、SVN与Apache综合
SVN与eclipse综合 下载SVN插入(http://subclipse.tigris.org) http://subclipse.tigris.org/servlets/ProjectDocum ...
- ASP.NET MVC4实现URL伪静态
1.在Web.config添加节点配置: <system.webServer> <modules runAllManagedModulesForAllRequests="t ...