How to avoid 内存碎片化

具体概念,在《Linux Kernel elementary Knowledge》中都有介绍。

影响也很简单:1、性能问题,大块的连续内存分配不到或者时间很长,导致卡顿。
2、浪费,大量内存碎片化了无法利用。
3、为了整理内存,kswapd和kcompactd频繁唤醒,占CPU,影响功耗。
尤其是相机、ion和gpu内存分配,都有分配连续物理内存的需求,ion是按8/9->4->0阶分配的,kernel-4.14之前的版本内核栈的16K都是连续的order=2的物理内存。

用户态有了MMU和页表,其实碎片化问题就很小了,缺页异常的时候多搞些离散的页面拼一拼就行了,主要还是内核态的问题。

简单讲下优化的一些思路:

1、虽然kernel-4.14开始内核栈用使用vmalloc分配,不过之前的版本,可以提前预留order = 2的页面供内核线程分配。kernelstack一般不超过250M,可以按这个size去配置适当的预留内存。
或者打开这个宏CONFIG_VMAP_STACK = y

2、ion_boost_pool 给ion分配做个pool
ion驱动里面申请的内存页面都是unmoveable的,更容易造成碎片问题。系统内存充足或者压力小时,就相机每次分配完ion内存后,就会触发下该缓存池的蓄水工作,会在系统里面再搞出很多连续free页面,加到该池子里面。那么下次再分配ion内存时,直接从池子里面取,这个pool的size最好是可配的,一般512M才会有明显效果,128效果非常有限。

这样每次ion内存分配都会聚合在一个地方(page pool)进行分配, unmoveable页面都会聚合在一起,不会再发散地分布在系统内存各个地方。然后等到系统的内存分配压力大时,这个page pool里面的缓存随时都可以被释放出来,满足系统其他地方的内存分配请求。详见代码:kernel/msm-4.19/drivers/staging/android/ion/ion_page_pool.c

3、kvmalloc()中,当分配size超过N个page,直接return到vmalloc,减少连续kmalloc的分配。

4、boost watermark 临时提高水位,并提前唤醒kswapd,防止外碎片化进一步恶化
限制内核page cache使用,虽然调大 vm.min_free_kbytes 确实会导致一些内存浪。但是旗舰手机总内存本身就大,内存充足,这个时候重点关注的是碎片化问题,那么就上boost watermark方案优化碎片。

5、最强优化,可以优化99%内存碎片化,保密哈哈~

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容