Android nativeメモリ割り当て2.0-private dirty memory回収しない


Context
シナリオ:
  • C++でmallocでメモリ
  • を申請する
  • 申請のメモリでモデルファイル
  • を読み取る.
  • メモリを解放し、Android StudioのProfilerはメモリサイズが変わらない
  • を表示します.
    分析ツール
  • adb shell dumpsys meminfo com.albertsnow.graphicdemo分析
  • 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の実際の消費メモリは変わらない
    追加の実験現象:
  • 携帯電話が画面を消した後、dirtyメモリは
  • に回収されます.
  • このロードロジックは、サービスにおいて、アプリケーションパッケージ名プロセスとは独立した個別のプロセスにある.しかし、この論理をメインプロセスに移行すると、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(ページ、サイズ4 K)を最小サイズとしてメモリにロードされます.diskのswap(スワップ)領域でバックアップします.両方が一致しない場合(memoryの変更はswapに書き込む時間がありません)
    例:
  • プロセスAはメモリにロードする(2つのpageに分けて)
  • .
  • ユーザーはプロセスBを起動するが、メモリは2つのpage(つまり8 K)しかないが、すでにAプロセスによって占有されている.
  • システムはプロセスA swapをディスクに、空の2つのpageをBプロセスに使用します.だからmemoryとdiskメモリの書き込みが一致しないのはdirty memoryです.

  • すぐに回収することができなくて、Exelを変更して、もとの基礎の上で多く書きました.Exel(release)を終了すると、アラートファイルが変更され(memory is dirty)閉じられません(release)