linux内存是支持numa,但是常用的uma。
其内存管理分3层:
1.zone这一层,主要是内存地址并不完全等价,ISA总线只能传输16MB地址,32bit高端内存的问题。所以会分几个区。
2.按page页粒度的buddy系统,alloc_pages,__get_freee_pages()这种按page order分配的管理系统。1- MAX_ORDER分组。它的优点在于效率与碎片比较均衡。
具体算法是分配时,从对应order去free_area[MAX_ORDER]找空闲的,如果找不到,就大order里面找。
释放时,如果有可合并的order,就合并出一个大的,达到一定程度防碎片的。
问题1:MAX_ORDER默认是11,也就是1024page。所以大内存是上限的,通常是4MB。
问题2: 最初的buddy是如何从zone中生成free的项? 是bootmem释放时free_all_bootmem()将zone里面的pages释放给buddy系统。也就是通过__free_pages(page, order)来释放进buddy系统。这会MAX_ORDER是最多的,不够整的page也会放入对应order,保证不会浪费一个page.
3.接下来是slab层,也就是小于page大小的分配器。基本的思想就是有很多相同大小的对象,频繁申请与释放。可以搞个池子。像kmalloc就是从这里面分配的。主要实现上分了free,partial,full三个list表。