Why use very little memory, it also GC?

Android applications built on the Java virtual machine, Google simultaneously in order to ensure more timely wake-run APP, it sets the maximum available memory for each virtual machine, you can view the adb command by several parameters,

* [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 which is the maximum amount of memory that can be used, this value has a relationship with the vendor with the release, with the improvement of configurations, are gradually increasing, since the virtual machine can use the maximum memory is dalvik.vm.heapsize, so at the time of application memory it is not up to a maximum GC will it? The answer is definitely no, we examined from the point of view of the curve, in low memory usage time, will GC, see the figure APP Run-time situation:

Seen from the chart, 1,2,3 three points seems to be have taken place in GC, but this time, not very high occupancy APP memory, maximum memory is still a long distance, it will happen this time why the memory GC does, in fact, the intuitive and easier to understand, if you waited until the maximum memory before GC, then there will be two drawbacks: first, memory waste of resources, resulting in reduced system performance, and secondly, the greater the GC when memory footprint, consuming more long, should be avoided. GC time that in the end is when? Is not always allocated memory block is going to be GC, this should also be negative, we have to simply understand the mechanisms under the memory allocation, GC, memory growth.

Android Dalvik virtual machine allocation and GC

First look at the significance of the configuration parameters of the virtual machine, the above only tells dalvik.vm.heapstartsize, is to apply the maximum memory size,

  • dalvik.vm.heapgrowthlimit and dalvik.vm.heapsize are java virtual machine's maximum memory limit, generally heapgrowthlimit <heapsize, if declared in the Manifest of application label android: largeHeap = "true", APP until heapsize only OOM, or OOM will reach heapgrowthlimit
  • Initial heap size dalvik.vm.heapstartsize Java, specifies the size of physical memory Davlik virtual machine applications to the system at boot time, back to the system and then gradually apply more physical memory as needed, until it reaches MAX
  • dalvik.vm.heapminfree minimum free heap value, after GC
  • dalvik.vm.heapmaxfree heap maximum idle value
  • dalvik.vm.heaptargetutilization heap target utilization

Three latter values ​​to ensure that the Java heap GC after each has been used and free memory has a suitable ratio, so you can try to reduce the number of GC, heap utilization U, is MinFree minimum idle bytes, the maximum MaxFree idle bytes is assumed that the GC after a certain time, survival is the size of memory occupied by the object LiveSize. So this time should be the ideal size for the heap (LiveSize / U). But (LiveSize / U) must be greater than or equal (LiveSize + MinFree) and less (LiveSize + MaxFree), otherwise adjustment is necessary, in fact, the adjustment softlimit soft cap,

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;
}

These are the source calculation formula, assuming liveSize = 150M, targetUtilization = 0.75, maxFree = 8, minFree = 512k, then the ideal size 200M, and 200M is significantly more than the 150 + 8, then this time, the stack size should be adjusted to 158M, this is a soft cap next softLimit whether the application memory when needed is an important indicator of the GC, consider the following scenario:

Scene One: Current softLimit = 158M, liveSize = 150M, if this time, the need to allocate a 100K memory object

Due to the current upper limit is 158M, the memory can be allocated directly to success, after the distribution, because the free memory 8-100K> 512k, do not need to adjust the memory, this time, GC does not exist,

Scene Two: Current softLimit = 158M, liveSize = 150M, if this time, the need to allocate memory is 7.7M

Due to the current upper limit is 158M, the memory can be allocated directly to success, after the distribution, because the free memory 8-7.7M <512k, it would need to GC, while adjusting softLimit

Scene Three: Current softLimit = 158M, liveSize = 150M, if this time, the need to allocate memory is 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移动架构总群】:加入群聊

资料大全

Guess you like

Origin blog.csdn.net/weixin_43351655/article/details/91491909