关于Android NDK使用malloc/alloc/new等方式创建的内存释放缓慢的问题
问题描述
在为Android Camera App采用NDK Native C++实现底层处理算法的时候,发现了一个问题:每次运行完算法,delete或者free确定调用完毕,但采用腾讯的Perfdog查看内存占用情况显示内存并未立刻被回收,如下图所示:

解决方法
1.malloc_trim(行不通)
在linux系统中,malloc.h文件中存在函数int malloc_trim(size_t)可以强制要求系统回收内存,但只能回收堆的前后区间,不能释放中间部分(所以叫做trim);
但在Android NDK上,Linux系统的一些底层操作是被禁止使用的,也就是malloc.h被阉割了,其中不存在malloc_trim函数,因此此方法行不通;
2.Allocation from stack instead of heap(可行)
由于stack上分配内存可以将所有分配内存的地址以及大小都预先告知给系统,系统内存调度模块就能感知把握全程,因此分配内存和释放内存都非常快,比如heap上new耗时70ms,而stack上分配内存是0ms,只有程序加载的耗时。为此,我将所有的new操作转换为临时数组,再次测试发现内存每次都能即时释放,如下图所示:

反思
对于C++程序,为了加速,应当尽可能将所有已知内存分配大小的变量全部转换为数组;
对于不能预先确定内存大小的变量,建议采用刻蚀的方式记录整体程序内存峰值,并以此峰值以64字节对齐的方式创建buffer数组,自行重载new/malloc等内存分配函数,使得所有的内存分配均发生在buffer上,即可以降低动态申请内存的耗时,又可以避免内存释放缓慢的问题导致平均内存占用过高。

浙公网安备 33010602011771号