如果这是一个愚蠢的问题,请道歉,但很长一段时间我都在困扰我。
我想了解内存管理器如何知道正在使用的内存的一些细节。
想象一下拥有1024B内存的单片机 - 没什么好处。
现在你分配 100 ints - 每个int 4个字节,每个指针 4个字节(是的,8位单片将最多可能有较小的指针,但w / e)。
所以你只用了100英镑 800B 的公羊?但情况更糟 - 分配系统必须以某种方式记录内存在哪里以及它的空闲位置 - 200个额外字节或其他什么?还是有点痕迹?
如果这是真的,为什么C经常偏爱汇编程序呢?
这真的是这样吗?那么超级低效?
答案 0 :(得分:9)
年轻的开发人员可能会惊讶地发现,像我这样老的老用户曾经用1或2k RAM的系统用C语言写作。
在这种规模的系统中,动态内存分配本来就是我们无法负担的奢侈品。它不仅仅是管理免费存储的指针开销,还有免费存储碎片的影响,使得内存分配效率低下,很可能导致致命的内存不足(虚拟内存不是一种选择)。
因此我们习惯使用静态内存分配(即全局变量),对所有嵌套的函数深度进行非常严格的控制,并对嵌套中断处理进行更严格的控制。
在这些系统上写作时,我甚至没有链接标准库。我编写了自己的C启动例程,并提供了自定义的最小I / O例程。
我在2k ram系统中编写的一个程序使用RAM的下半部分作为数据区域,上部部分作为堆栈。在最后的剪辑中,我证明了堆栈的最大使用量在内存中达到了目前为止,它与数据区域中的最后一个变量相距1个字节。
啊,过去的美好时光......编辑:
要具体回答您的问题,原来的K& R免费商店管理员用于将标题块添加到通过malloc
分配的每个内存块的开头。
标题栏看起来像这样:
union header {
struct {
union header *ptr;
unsigned size;
} s;
};
其中ptr
是下一个标题块的地址,大小是分配的内存大小(以块为单位)。 malloc
函数实际上将返回&header + sizeof(header)
计算的地址。 free函数会从你提供的指针中减去标题的大小,以便将块重新链接回空闲列表。
答案 1 :(得分:2)
有几种方法可以做到这一点:
malloc()
每个int
一个内存块。完全没效率,因此我将其删除。malloc()
一个100 int
的数组。无论100*sizeof(int) + 1* sizeof(int*) +
内部需要什么,总共需要malloc()
。好多了。100*sizeof(int)
。您需要哪些内容取决于您需要多长时间的内存和其他标准。
如果你的内存很少,那么使用malloc()
是否有用甚至可能会有问题。如果几个代码块需要大量RAM,但不能同时使用,那么它可以是一个选项。
关于如何跟踪内存地址,这也取决于:
malloc()
,你必须将指针放在一个你不会丢失它的地方。答案 2 :(得分:0)
如果这是真的,为什么C常常比汇编器更受青睐?
您过度简化了问题。 C或汇编程序 - 无所谓,你仍然需要管理内存块。主要问题是碎片,而不是实际的管理开销。在你所描述的系统中,你可能只是分配内存并且永远不会释放它,因此无需检查什么是免费的 - 水印以下的任何东西都是免费的,而这就是它。
这真的是这样吗?那么超级低效?
围绕这个问题有很多算法,但是如果你要简化 - 是的,它基本上是。实际上它是一个更复杂的问题 - 还有更复杂的系统围绕服务内存,处理碎片,垃圾收集(在操作系统级别)等等。