zygote堆

121 阅读2分钟

 zygote启动的时候先创建一个active堆,等第一次fork子进程的时候再创建zygote堆

active堆创建

dvmGcStartup  ->   dvmHeapStartup->dvmHeapSourceStartup->

GcHeap* dvmHeapSourceStartup(size_t startSize, size_t maximumSize,  
                             size_t growthLimit)  
{  
    GcHeap *gcHeap;  
    HeapSource *hs;  
    mspace msp;  
    size_t length;  
    void *base;  
    ......  
  
    /* 
     * Allocate a contiguous region of virtual memory to subdivided 
     * among the heaps managed by the garbage collector. 
     */  
    length = ALIGN_UP_TO_PAGE_SIZE(maximumSize);  
    base = dvmAllocRegion(length, PROT_NONE, gDvm.zygote ? "dalvik-zygote" : "dalvik-heap");  
    ......  
  
    /* Create an unlocked dlmalloc mspace to use as 
     * a heap source. 
     */  
    msp = createMspace(base, kInitialMorecoreStart, startSize);  
    ......  
  
    gcHeap = (GcHeap *)calloc(1, sizeof(*gcHeap));  
    ......  
  
    hs = (HeapSource *)calloc(1, sizeof(*hs));  
    ......  
  
    hs->targetUtilization = gDvm.heapTargetUtilization * HEAP_UTILIZATION_MAX;  
    hs->minFree = gDvm.heapMinFree;  
    hs->maxFree = gDvm.heapMaxFree;  
    hs->startSize = startSize;  
    hs->maximumSize = maximumSize;  
    hs->growthLimit = growthLimit;  
    ......   
    hs->numHeaps = 0;  
    ......  
    hs->heapBase = (char *)base;  
    hs->heapLength = length;  
    ......  
  
    if (!addInitialHeap(hs, msp, growthLimit)) {  
        ......  创建一个Active堆。
    }  
    if (!dvmHeapBitmapInit(&hs->liveBits, base, length, "dalvik-bitmap-1")) {  
        ......  创建和初始化一个Live Bitmap
    }  
    if (!dvmHeapBitmapInit(&hs->markBits, base, length, "dalvik-bitmap-2")) {  
        ......  创建和初始化一个Mark Bitmap,
    }  
    if (!allocMarkStack(&gcHeap->markContext.stack, hs->maximumSize)) {  
        ......  创建和初始化一个Mark Stack
    }  
    gcHeap->markContext.bitmap = &hs->markBits;  
    gcHeap->heapSource = hs;  
  
    gHs = hs;  
    return gcHeap;  
  
    ......  
}

函数dvmHeapSourceStartup的执行过程如下所示:

  1. 将参数maximum指定的最大堆大小对齐到内存页边界,得到结果为length,并且调用函数dvmAllocRegion分配一块大小等于length的匿名共享内存块,起始地址为base。这块匿名共享内存即作为Dalvik虚拟机的Java堆。

  2. 调用函数createMspace将前面得到的匿名共享内存块封装为一个mspace,以便后面可以通过C库得供的mspace_malloc和mspace_bulk_free等函数来管理Java堆。这个mspace的起始大小为Java堆的起始大小,这意味着一开始在该mspace上能够分配的内存不能超过Java堆的起始大小。不过后面我们动态地调整这个mspace的大小,使得它可以使用更多的内存,但是不能超过Java堆的最大值。
    3, 分配一个GcHeap结构体gcHeap和一个HeapSource结构体hs,用来维护Java堆的信息,包括Java堆的目标利用率、最小空闲值、最大空闲值、起始大小、最大值、增长上限值、堆个数、起始地址和大小等信信息。

  3. 调用函数addInitialHeap在前面得到的匿名共享内存上创建一个Active堆。这个Active堆的最大值被设置为Java堆的起始大小。

  4. 调用函数dvmHeapBitmapInit创建和初始化一个Live Bitmap和一个Mark Bitmap,它们在GC时会用得到。

  5. 调用函数allockMarkStack创建和初始化一个Mark Stack,它在GC时也会用到。

  6. 将前面创建和初始化好的Mark Bitmap和HeapSource结构体hs保存在前面创建的GcHeap结构体gcHeap中,并且将该GcHeap结构体gcHeap返回给调用者。同时,HeapSource结构体hs也会保存在全局变量gHs中

zygote堆创建

forkAndSpecializeCommon ->  dvmHeapSourceStartupBeforeFork  

bool dvmHeapSourceStartupBeforeFork()  
{  
    HeapSource *hs = gHs; // use a local to avoid the implicit "volatile"  
  
    HS_BOILERPLATE();  
  
    assert(gDvm.zygote);  
  
    if (!gDvm.newZygoteHeapAllocated) {  
       /* Ensure heaps are trimmed to minimize footprint pre-fork. 
        */  
        trimHeaps();  此处清理收缩堆空间
        /* Create a new heap for post-fork zygote allocations.  We only 
         * try once, even if it fails. 
         */  
        ALOGV("Splitting out new zygote heap");  
        gDvm.newZygoteHeapAllocated = true;  
        return addNewHeap(hs);  此处增加zygote堆
    }  
    return true;  
}