Android native内存分配2.0-private dirty memory不回收

Context

情景:

  1. 在C++中用 malloc申请内存
  2. 用申请的内存读取 模型文件
  3. 释放内存,AndroidStudio的Profiler显示内存大小不变

分析工具

  1. adb shell dumpsys meminfo com.albertsnow.graphicdemo分析
  2. Android Studio的profiler功能

输出形式

//仅用于数据名称演示,非本case的实际dump信息
                   Pss  Private  Private     Swap     Heap     Heap     Heap
                 Total    Dirty    Clean    Dirty     Size    Alloc     Free
                ------   ------   ------   ------   ------   ------   ------
  Native Heap        0        0        0        0    12288     9963     2324
  Dalvik Heap        0        0        0        0     4952     2971     1981
        TOTAL        0        0        0        0    17240    12934     4305
         Native Heap:        0
               TOTAL:        0      TOTAL SWAP (KB):        0

观察结果:

malloc内存分配在Private dirty部分,release后 Heap size已经下降,但是Private Dirty并没有下降。导致进程dump出的实际占用 内存不变

额外的实验现象:

  1. 手机亮灭屏后,dirty内存会被回收
  2. 该加载逻辑在Service中,Service在独立于应用包名进程的单独进程中。但将该逻辑移到主进程中,dirty也会被回收

推测:

是系统对不同的进程状态,有不同的回收策略

代码解决:

 mmap(NULL, chunck_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);

代替malloc。原理 StackOverFlow link

进程memory Private & Public

进程共享的内存(Android的SDK代码)为public。进程独享的为private

进程clean dirty

进程的虚拟内存以page(页,大小4K)为最小大小,加载于内存中。并且在disk的swap(交换)区备份,如果两方不一致(memory的更改,还没来得及写入swap)

举例:
  1. 进程A加载于内存中(分为2个page)
  2. 用户启动进程B,但内存只有2个page(也就是8K),但已经被A进程占用。
  3. 系统就会吧 进程A swap到磁盘上,空出的2个page给B进程用。
    所以 memory与disk内存书写不一致,就是dirty memory。

而无法立即回收,更改Exel,在原来基础上写了很多。等到退出Exel(release)时,提醒文件已经被更改(memory is dirty)无法关闭(release)

展开阅读全文

没有更多推荐了,返回首页