なぜ、それはまた、GC、非常に少ないメモリを使うのか?

Java仮想マシン上に構築されたAndroidアプリケーションは、Googleは同時に、よりタイムリーなウェイクランAPPを確保するためには、各仮想マシンの最大使用可能なメモリを設定し、あなたはいくつかのパラメータでのadbコマンドを表示することができ、

* [dalvik.vm.heapgrowthlimit]: [192m]
* [dalvik.vm.heapmaxfree]: [8m]
* [dalvik.vm.heapminfree]: [512k]
* [dalvik.vm.heapsize]: [512m]
* [dalvik.vm.heapstartsize]: [8m]
* [dalvik.vm.heaptargetutilization]: [0.75]

使用可能なメモリの最大量であるDalvik.vm.heapsize、この値は構成の改善とリリースとベンダーとの関係を有している仮想マシンが最大メモリはdalvik.vm.heapsizeで使用することができるので、徐々に増加しています、そのアプリケーションメモリの時点では、最大GCますが、それまでではないでしょうか?答えは間違いありません、我々は曲線の観点から検討し、低メモリ使用時に、図APPランタイム状況を確認、GCされますされています。

チャートから見ると、1,2,3の3点がGCで行われてきているようだが、今回、ない非常に高い占有APPメモリは、最大メモリはまだ長い距離が、それは今回が起こるのだろう、なぜメモリあなたはGC前の最大メモリまで待っていた場合はGCは、実際には、直感的かつ簡単に、理解することはない、その後、2つの欠点があります:低下し、システムの性能が得まず、リソースのメモリの浪費、そして第二に、より大きなメモリフットプリント、より多くを消費GC長い、避けるべきです。最後になっていることをGC時間?常に割り当てられたメモリブロックは、GCになるだろうされていない、これも負である必要があり、我々は単にメモリの割り当て、GC、メモリの成長の下でのメカニズムを理解する必要があります。

アンドロイドのDalvik仮想マシンの割り当ておよびGC

仮想マシンの設定パラメータの重要性を初めて目には、唯一のdalvik.vm.heapstartsizeを伝える上で、最大メモリサイズを適用することで、

  • ヒープサイズのみOOMまで、largeHeap =「true」のAPP、または:dalvik.vm.heapgrowthlimitとdalvik.vm.heapsizeは、アプリケーションのラベルアンドロイドのマニフェストで宣言された場合、一般的にheapgrowthlimit <ヒープサイズ、Java仮想マシンの最大メモリ制限ありOOMはheapgrowthlimitに到達します
  • 初期ヒープサイズdalvik.vm.heapstartsizeジャワ、バックシステムに、ブート時にシステムに物理メモリDavlik仮想マシンのアプリケーションのサイズを指定し、必要に応じてそれがMAXに達するまで徐々に、より多くの物理メモリを適用
  • GC後、最小空きヒープ値をdalvik.vm.heapminfree
  • dalvik.vm.heapmaxfreeヒープ最大アイドル値
  • dalvik.vm.heaptargetutilizationヒープターゲットの利用

三の後者の値は、それぞれが使用されており、空きメモリが適切な比率を持っているので、あなたは、GCの数を減らすことを試みることができた後のJavaヒープGCいることを確実にするために、ヒープ使用率Uは、MINFREEの最小アイドルバイト、最大でMAXFREEアイドルバイトは、一定時間後にGCは、生存オブジェクトLiveSizeによって占められるメモリのサイズであると仮定されます。したがって、この時間は、ヒープ(LiveSize / U)のための理想的なサイズである必要があります。しかし、(LiveSize / U)(LiveSize + MAXFREE)以上(LiveSize + MINFREE)未満でなければならない、そうでなければ調整が必要であり、実際には、調整は、ソフトキャップソフト限界、

static size_t getUtilizationTarget(const HeapSource* hs, size_t liveSize)
{
    size_t targetSize = (liveSize / hs->targetUtilization) * HEAP_UTILIZATION_MAX;

    if (targetSize > liveSize + hs->maxFree) {
        targetSize = liveSize + hs->maxFree;
    } else if (targetSize < liveSize + hs->minFree) {
        targetSize = liveSize + hs->minFree;
    }
    return targetSize;
}

これらはliveSize = 150M、targetUtilization = 0.75、MAXFREE = 8、MINFREE = 512K、その後、理想サイズ200Mを仮定すると、元計算式であり、そして200Mは150 + 8よりも有意であり、この時間は、スタックサイズはに調整されるべきです158Mは、これはソフトリミットが必要なアプリケーションメモリは、GCの重要な指標であるかどうか、次のシナリオを検討してください横ソフトキャップです。

シーンワン:現在、ソフト限界= 158M、liveSize = 150M、今回の場合、100Kのメモリオブジェクトを割り当てる必要

現在の上限は158Mであるために8-10​​0K> 512K、メモリを調整する必要はありません、この時間は、GCが存在しない空きメモリので、メモリは、配布後に、直接、成功に割り当てることができます

シーン2:現在、ソフト限界= 158M、liveSize = 150Mは、この時間ならば、メモリを割り当てる必要が7.7Mであります

現在の上限は158Mであるために、空きメモリ8-7.7M <512Kが、それはGCに必要となるので、メモリがソフトリミットを調整しながら、配布後、成功に直接割り当てることができます

シーン3:現在、ソフト限界= 158M、liveSize = 150Mは、この時間ならば、メモリを割り当てる必要が10Mであります

由于当前的上限是158M,内存分配失败,需要先GC,GC之后调整softLimit,再次请求分配,如果还是失败,将softLimit调整为最大,再次请求分配,失败就再GC一次软引用,再次请求,还是失败那就是OOM,成功后要调整softLimit

所以,Android在申请内存的时候,可能先分配,也可能先GC,也可能不GC,这里面最关键的点就是内存利用率跟Free内存的上下限,下面简单看源码了解下堆内存分配流程:

   static void *tryMalloc(size_t size)
    {
        void *ptr;
        <!--1 首次请求分配内存-->
        ptr = dvmHeapSourceAlloc(size);
        if (ptr != NULL) {
            return ptr;
        }
        <!--2 分配失败,GC-->
        if (gDvm.gcHeap->gcRunning) {
            dvmWaitForConcurrentGcToComplete();
        } else {
          gcForMalloc(false);
        }
        <!--再次分配-->
        ptr = dvmHeapSourceAlloc(size);
        if (ptr != NULL) {
            return ptr;
        }
         <!--还是分配失败,调整softLimit再次分配-->
        ptr = dvmHeapSourceAllocAndGrow(size);
        if (ptr != NULL) {
            size_t newHeapSize;
       <!--分配成功后要调整softLimit-->
            newHeapSize = dvmHeapSourceGetIdealFootprint();
            return ptr;
        }
         <!--还是分配失败,GC力加强,回收soft引用,-->
        gcForMalloc(true);
        <!--再次请求分配,如果还是失败,那就OOM了-->
        ptr = dvmHeapSourceAllocAndGrow(size);
        if (ptr != NULL) {
            return ptr;
        }
        dvmDumpThread(dvmThreadSelf(), false);          return NULL;  
        }

总结

本文主要说的一个问题就是,为什么不等到最大内存在GC,以及普通GC的可能时机,当然,对于内存的GC是更加复杂的,不在本文的讨论范围之内,同时这个也解释频繁的分配大内存会导致GC抖动的原因,毕竟,如果你超过了maxFree ,就一定GC,有兴趣可以自行深入分析。

自己是从事了七年开发的Android工程师,不少人私下问我,2019年Android进阶该怎么学,方法有没有?

没错,年初我花了一个多月的时间整理出来的学习资料,希望能帮助那些想进阶提升Android开发,却又不知道怎么进阶学习的朋友。【包括高级UI、性能优化、架构师课程、NDK、Kotlin、混合式开发(ReactNative+Weex)、Flutter等架构技术资料】,希望能帮助到您面试前的复习且找到一个好的工作,也节省大家在网上搜索资料的时间来学习。

资料获取方式:加入Android架构交流QQ群聊:513088520 ,进群即领取资料!!!

点击链接加入群聊【Android移动架构总群】:加入群聊

资料大全

おすすめ

転載: blog.csdn.net/weixin_43351655/article/details/91491909
おすすめ