4

您如何手动管理 mips 程序集中的堆,特别是 SPIM 模拟器?

使用 sbrk 系统调用时,我发现堆从 0x10040000 开始,例如

li $t0, 1

li $s0, 9

syscall

sw $t0, ($s0) # 1 located at 0x10040000

那么,调用 sbrk 是否不能保证您将取回下一个空闲内存插槽?例如,如果我为单个 4 字节空间调用 sbrk,SPIM 可能会分配地址:0x10040000-0x10040003。但是,第二次调用另一个 4 字节空间可能与之前的 4 字节分配无关?因此,需要一个数据结构来跟踪哪些内存插槽已被分配?最后,内存管理器是否尝试通过确定特定数据结构跟踪的地址之间的空闲空间来减少对 sbrk 的调用次数?

4

1 回答 1

6

在真实系统上,sbrk 返回页面粒度分配。我不确定 SPIM 模拟器是否可以(微薄的在线文档暗示它将返回任何面向字节的粒度)。

通常,sbrk 系统调用只是设置“堆尾”指针。底层操作系统所知道的只是堆的开头(sbrk 在程序的开头开始)和当前的堆尾指针。该范围内的所有内存都被视为(从操作系统的角度来看)程序正在使用的堆内存。

(注意,在你的情况下,我相信 SPIM 模拟器需要一个整数来碰撞指针,所以隐含的所有内存都是连续的,我认为中断总是在增加?)

通常基于 sbrk 构建的“malloc”API 提供的不仅仅是一个简单的连续、不断增长的内存区域。一个好的 malloc 库通常可以让您将内存区域标记为“空闲”(因此它可以用来满足后续的 malloc 调用)。请注意,操作系统通常不知道这个“免费”。Malloc 跟踪是否空闲的内存。通常 malloc 不能将堆的这个任意区域返回给操作系统,因为从操作系统的角度来看,堆是单个连续区域。

真正的 malloc 实现必须处理分配请求和页面大小之间的不匹配(正常的 sbrk 只返回页面对齐、页面大小分配的倍数)。您的模拟器案例没有这个问题,因为 sbrk 是细粒度的。

请注意,跟踪正在使用或不使用的内存需要内存,因此 malloc 有一些开销。一些实现旨在将大部分簿记存储在“空闲”内存中(减少客户端的明显成本)。还有很多其他策略可以将 malloc 与 sbrk 匹配....(在您的情况下,将 malloc 映射到 sbrk,并且只要您不分配太多内存,就可以释放空操作...)

以下是如何绘制一些 ASCII 艺术的概述mallocsbrk相关性,我没有耐心转录: http ://web.eecs.utk.edu/~huangj/cs360/360/notes/Malloc1/lecture.html

于 2012-02-08T07:13:30.430 回答