这次更新第9章习题。

参考资料:

9.11~9.13的参考资料:

虚拟地址:

TLB:

页表:

物理地址:

高速缓存:

备注:

TLB是PTE的缓存。

9.11

A

虚拟地址格式:

B

注意此时TLB不命中,所以要检查PTE,结果如下:

C

物理地址格式:

D

物理地址引用:

9.12

A

虚拟地址格式:

B

地址翻译:

C

物理地址格式:

D

物理地址引用:

9.13

A

虚拟地址格式:

B

地址翻译:

C

略过

D

略过。

9.14

参考资料:

代码:

#include <stdio.h>
#include "csapp.h"

int main(){
    struct stat stat;
    int fd;

    // O_RDWR为权限
    fd = Open("hello.txt", O_RDWR, 0);
    // 获得大小
    fstat(fd, &stat);
    char *bufp;
    // shared保证为共享对象
    bufp = Mmap(NULL, stat.st_size, PROT_WRITE, MAP_SHARED, fd, 0);
    bufp[0] = 'J';
    // 删除内存
    Munmap(bufp, stat.st_size);

    // test
    fd = Open("hello.txt", O_RDONLY, 0);
    fstat(fd, &stat);
    bufp = Mmap(NULL, stat.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
    Write(1, bufp, stat.st_size);

    return 0;
}

编译命令:

gcc -o 9.14 9.14.c -lpthread

hello.txt before:

Hello, world!

hello.txt after:

Jello, world!

9.15

注意头部需要4字节,大小为整个块的大小:

9.16

说明:

round表示对齐。

9.17

见lab。

9.18

见lab。

9.19

1
  • a) 在一个伙伴系统中, 最高可达 $50 \%$ 的空间可以因为内部碎片而被浪费了。
    • 错误;
  • b) 首次适配内存分配算法比最佳适配算法要慢一些(平均而言)。
    • 错误,显然首次适配更快;
  • c) 只有当空闲链表按照内存地址递增排序时,使用边界标记来回收才会快速。
    • 正确;
  • d) 伙伴系统只会有内部碎片,而不会有外部碎片。
    • 错误;
2
  • a) 在按照块大小递减顺序排序的空闲链表上, 使用首次适配算法会导致分配性能很低, 但是可以避免外部碎片。
    • 错误;
  • b) 对于最佳适配方法,空闲块链表应该按照内存地址的递增顺序排序。
    • 正确;
  • c)最佳适配方法选择与请求段匹配的最大的空闲块。
    • 错误;
  • d) 在按照块大小递增的顺序排序的空闲链表上, 使用首次适配算法与使用最佳适配算法等价。
    • 错误;
3

Mark\&Sweep 垃圾收集器在下列哪种情况下叫做保守的:

  • a) 它们只有在内存请求不能被满足时才合并被释放的内存。
  • b) 它们把一切看起来像指针的东西都当做指针。
  • c) 它们只在内存用尽时, 才执行垃圾收集。
  • d) 它们不释放形成循环链表的内存块。

b

9.20

见lab。