8/29 深入理解计算机系统 垃圾收集器

9.10 垃圾收集

垃圾收集器是一种动态内存分配器,它自动释放程序不再需要的已分配块。它定期识别垃圾块,调用相应的free,并把这些块放在空闲链表中。

垃圾收集器将内存视为一张有向可达图,图包括根节点堆节点
每个堆节点对应堆中的一个已分配块。边的方向表示块p中的某个位置指向q的某个位置。根节点是不在堆中,但是包含指向堆的指针。

如果不存在由任意根节点指向p的有向路径,则此节点是不可达的,是垃圾。

JAVA对创建和使用指针有严格的控制,所以可以用可达图精确的表示,但C和C++不行。所以采取的是保守的垃圾收集器。
保守的垃圾收集器只有当malloc找不到空闲块时,调用垃圾收集器,识别垃圾块,调用free。
如果malloc还是失败了就向操作系统分配额外的内存。

Mark & Sweep垃圾收集器
由标记阶段和清除阶段组成:

  1. 标记阶段标记出所有根节点可达的后继
  2. 消除阶段释放每个未被标记的已分配块

mark函数一次标记一个根节点的所有未被标记的已分配块
sweep函数在堆中的每个块反复循环,释放它所遇到的所有未标记的已分配块。

C语言中,指针可能不会显示的表明是指针,而是用int。
isptr用平衡二叉树来查找指针是否落在某个块之内。

9.11 C程序常见错误

  1. 间接引用坏指针
  2. 读未初始化的内存(堆内存不会初始化为0)
  3. 允许栈缓冲区溢出(读一个未知的串到有限的数组里)
  4. 假设指针和它们指向的对象是相同大小的(分配内存时sizeof(int)少了号)
  5. 造成错位的错误(创建的数组大小是n,初始化了下标为n的元素(第n+1个))
  6. 误解指针运算(步长不是按位而是按指向的类型)
  7. 引用不存在的变量(返回已经回收局部变量)
  8. 引用空闲块中的数据
  9. 引起内存泄漏
posted @ 2022-08-29 22:00  227569hy  阅读(40)  评论(0)    收藏  举报