9.11 A、虚拟地址格式:00001001 111100
B、
参数 | 值 |
---|---|
VPN | 0x09 |
TLB索引 | 0x1 |
TLB标记 | 0x02 |
TLB命中?(是/否) | 否 |
缺页?(是/否) | 否 |
PPN | 0x17 |
C、物理地址格式:010111 111100
D、
参数 | 值 |
---|---|
字节偏移 | 0x0 |
缓存索引 | 0xF |
缓存标记 | 0x17 |
缓存命中?(是/否) | 否 |
返回的缓存字节 | 无 |
9.12 A、虚拟地址格式:00001110 101001
B、
参数 | 值 |
---|---|
VPN | 0x0E |
TLB索引 | 0x2 |
TLB标记 | 0x03 |
TLB命中?(是/否) | 否 |
缺页?(是/否) | 否 |
PPN | 0x11 |
C、物理地址格式:010001 101001
D、
参数 | 值 |
---|---|
字节偏移 | 0x1 |
缓存索引 | 0xA |
缓存标记 | 0x11 |
缓存命中?(是/否) | 否 |
返回的缓存字节 | 无 |
9.13 A、虚拟地址格式:00000001 000000
B、
参数 | 值 |
---|---|
VPN | 0x01 |
TLB索 | 0x1 |
TLB标记 | 0x00 |
TLB命中?(是/否) | 否 |
缺页?(是/否) | 是 |
PPN |
9.14
#include "csapp.h"
int main(int argc, char const *argv[])
{
int fd;
if ((fd = open("hello.txt", O_RDWR)) == -1)
{
perror("Failed to open hello.txt");
exit(EXIT_FAILURE);
}
struct stat stat_of_file;
if (fstat(fd, &stat_of_file) == -1)
{
perror("Failed to get stat of hello.txt");
exit(EXIT_FAILURE);
}
char *p;
if ((p = mmap(NULL, stat_of_file.st_size, PROT_WRITE, MAP_SHARED,
fd, 0)) == (void *)-1)
{
perror("Failed to mmap");
exit(EXIT_FAILURE);
}
p[0] = 'J';
return 0;
}
9.15
请求 | 块大小(十进制字节) | 块头部(十六进制) |
---|---|---|
malloc(3) | 8 | 0x09 |
malloc(11) | 16 | 0x11 |
malloc(20) | 24 | 0x19 |
malloc(21) | 32 | 0x21 |
9.16
对齐要求 | 已分配块 | 空闲块 | 最小块大小(字节) |
---|---|---|---|
单字 | 头部和脚部 | 头部和脚部 | 16 |
单字 | 头部,但没有脚部 | 头部和脚部 | 16 |
双字 | 头部和脚部 | 头部和脚部 | 16 |
双字 | 头部,但没有脚部 | 头部和脚部 | 16 |
9.17 罗列下修改的要点:
1、新增一个静态全局变量rover,保存上一次搜索的结果地址;在mm_init函数里初始化为堆的起始地址heap_listp
2、修改find_fit,从rover开始到堆尾,再从heap_listp到rover,搜索合适的空闲块。
3、修改mm_malloc,正确分配块后,将rover置为下一个空闲块。
4、mm_free需修改,修改coalesce,在合并时更新rover。
9.18 说明:用Header的倒数第二位表示是否为空闲位。如010表示上一个块已分配,000表示未分配。由于只在合并块时需要使用上一个块的大小。所以取消已分配块的Footer不影响算法的实现。由于细节的修改比较多,此处略过。
9.19 1)a:正确,假设申请一个大小的块,实际会分配
,所以最高约有50%的空间浪费;
b:错误,无论是考虑平均,还是最差情况,两种算法的复杂度都与块数量呈线性关系;
c:错误,比如伙伴系统就不需要使用边界标记,空闲链表也不一定需要按地址递增排序;
d:错误,任何分配器都会有外部碎片。
2)a:错误,空闲块递减排列使得首次适配算法的匹配复杂度为O(1),性能是提升了;且不能避免外部碎片;
b:错误:最佳适配无论如何都要搜索整个链表,顺序安排无所谓;
c:错误:请求的是最接近请求大小的适配块;
d:正确:两者找到的肯定是同一个块,所以等价 。
3)b:正确,保守是说会将垃圾当成可达块,而原因正是将一些非指针值,如int当作指针值,而错误地将一些垃圾标记位可达块,而不回收它。a)c)不保守的垃圾收集器也是可以这么做的,d)循环链表的垃圾块也是可能被回收的。
9.20 略