内存回收
内存使用完之后必须要进行释放,通过 huge 方式和 large 方式申请的内存的释放比较简单,前面已经讲过。这里主要介绍 small 内存的释放。
释放 small 内存的一个 slot 时,并没有判断此 slot 所在的连续 page 中的 slot 是否已全部释放。因为 small 内存的申请和释放比较频繁,每次都判断不太划算,但 MM 在申请 chunk 失败后,会进行内存整理。如果一次申请 small 内存申请到的连续 page 中的 slot 已全部释放,则释放这几个 page,再继续申请 chunk。
-
依次遍历 30 种 RUN 的单向链表。
-
根据内存地址对齐的相关宏,可以轻松定位到一个 slot 所在的 page(假定 page 所在 chunk 的编号为 page_num)、chunk。
-
chunk→map[page_num] 的高 2bit 如果为 0x10,则说明此 page 为连续 page 的首个 page, chunk→map[page_num] 的中间 9bit进行+1操作。
-
chunk→map[page_num] 的高 2bit 如果为 0x11,则说明此 page 为连续 page 的非首个 page,假定为 page_offset 个 page,则 chunk→map[page_num-page_offset] 的中间 9bit 进行+1操作。
-
+1 操作后,如果发现中间 9bit 的值与这一次申请此规格的 RUN 时分配的 slot 个数相等,则说明此连续 page 可以进行释放。
-
重新遍历此 RUN 的单向链表,将可释放 page 中的 slot 全部删除,然后释放所占的 page,将不可释放的 slot 所在连续 page 的首个 page 中的 map 信息中的中间 9bit 置 0。