heap gc3

//遍历bitmap,找到垃圾对象的指针,回调相关函数

void dvmHeapBitmapSweepWalk(const HeapBitmap *liveHb, const HeapBitmap *markHb,

                            uintptr_t base, uintptr_t max,

                            BitmapSweepCallback *callback, void *callbackArg)

{

    assert(liveHb != NULL);

    assert(liveHb->bits != NULL);

    assert(markHb != NULL);

    assert(markHb->bits != NULL);

    assert(liveHb->base == markHb->base);

    assert(liveHb->bitsLen == markHb->bitsLen);

    assert(callback != NULL);

    assert(base <= max);

    assert(base >= liveHb->base);

    assert(max <= liveHb->max);

    if (liveHb->max < liveHb->base) {

        /* Easy case; both are obviously empty.

         */

        return;

    }

    void *pointerBuf[4 * HB_BITS_PER_WORD];

    void **pb = pointerBuf;

                //live bits跟踪分配回收代码

    size_t start = HB_OFFSET_TO_INDEX(base - liveHb->base);

    size_t end = HB_OFFSET_TO_INDEX(max - liveHb->base);

    unsigned long *live = liveHb->bits;

    unsigned long *mark = markHb->bits;

    for (size_t i = start; i <= end; i++) {

                                //live = 0 mark = 1 代码层已经free,但是可达,说明有引用指向该对象 garbage = 0

                                //live = 0 mark = 0 代码层已经free,且不可达,不视为垃圾 garbage = 0

                                //live = 1 mark = 0 代码层未free,但是已经不可达,视为垃圾 garbage = 1

                                //live = 1 mark = 1 代码层未free,且可达,该对象不可回收 garbage = 0

        unsigned long garbage = live[i] & ~mark[i];

        if (UNLIKELY(garbage != 0)) {

            unsigned long highBit = 1 << (HB_BITS_PER_WORD - 1);

            uintptr_t ptrBase = HB_INDEX_TO_OFFSET(i) + liveHb->base;

            while (garbage != 0) {

                int shift = CLZ(garbage);

                garbage &= ~(highBit >> shift);

                                                                //pointer Buffer存放将要回收的地址

                *pb++ = (void *)(ptrBase + shift * HB_OBJECT_ALIGNMENT);

            }

            /* Make sure that there are always enough slots available */

            /* for an entire word of 1s. */

                                                //pointer Buffer始终保留了一个word的大小

            if (pb >= &pointerBuf[NELEM(pointerBuf) - HB_BITS_PER_WORD]) {

                (*callback)(pb - pointerBuf, pointerBuf, callbackArg);

                pb = pointerBuf;

            }

        }

    }

    if (pb > pointerBuf) {

        (*callback)(pb - pointerBuf, pointerBuf, callbackArg);

    }

}

static void sweepBitmapCallback(size_t numPtrs, void **ptrs, void *arg)

{

    assert(arg != NULL);

    SweepContext *ctx = (SweepContext *)arg;

    if (ctx->isConcurrent) {

        dvmLockHeap();

    }

    ctx->numBytes += dvmHeapSourceFreeList(numPtrs, ptrs);

    ctx->numObjects += numPtrs;

    if (ctx->isConcurrent) {

        dvmUnlockHeap();

    }

}

void dvmHeapSourceGrowForUtilization()

{

    HS_BOILERPLATE();

 

    HeapSource *hs = gHs;

    Heap* heap = hs2heap(hs);

 

    /* Use the current target utilization ratio to determine the

     * ideal heap size based on the size of the live set.

     * Note that only the active heap plays any part in this.

     *

     * Avoid letting the old heaps influence the target free size,

     * because they may be full of objects that aren't actually

     * in the working set.  Just look at the allocated size of

     * the current heap.

     */

    size_t currentHeapUsed = heap->bytesAllocated;

    size_t targetHeapSize = getUtilizationTarget(hs, currentHeapUsed);

 

    /* The ideal size includes the old heaps; add overhead so that

     * it can be immediately subtracted again in setIdealFootprint().

     * If the target heap size would exceed the max, setIdealFootprint()

     * will clamp it to a legal value.

     */

    //此部分为非要不可的内存大小

    size_t overhead = getSoftFootprint(false);

    setIdealFootprint(targetHeapSize + overhead);

 

    size_t freeBytes = getAllocLimit(hs);

    if (freeBytes < CONCURRENT_MIN_FREE) {

        /* Not enough free memory to allow a concurrent GC. */

        heap->concurrentStartBytes = SIZE_MAX;

    } else {

        //For small footprint, we keep the min percentage to start

        //concurrent GC; for big footprint, we keep the absolute value

        //of free to start concurrent GC

        heap->concurrentStartBytes = freeBytes - MIN(freeBytes * (float)(0.2), concurrentStart);

    }

 

    /* Mark that we need to run finalizers and update the native watermarks

     * next time we attempt to register a native allocation.

     */

    gHs->nativeNeedToRunFinalization = true;

}

static void markObjectNonNull(const Object *obj, GcMarkContext *ctx,

                              bool checkFinger)

{

    assert(ctx != NULL);

    assert(obj != NULL);

    assert(dvmIsValidObject(obj));

    if (obj < (Object *)ctx->immuneLimit) {

        assert(isMarked(obj, ctx));

        return;

    }

                //heapbitmap里标记

                //如果之前标记过会返回之前的标记值

    if (!setAndReturnMarkBit(ctx, obj)) {

        /* This object was not previously marked.

         */

        //如果之前未出现过,压入栈

        //将对象的字段对象压入栈,如果以前已经设过标记值,则不压入栈,避免死循环

        if (checkFinger && (void *)obj < ctx->finger) {

            /* This object will need to go on the mark stack.

             */

            markStackPush(&ctx->stack, obj);

        }

    }

}

static unsigned long _heapBitmapModifyObjectBit(HeapBitmap *hb, const void *obj,

                                                bool setBit, bool returnOld)

{

    const uintptr_t offset = (uintptr_t)obj - hb->base;

                //indexoffset的关系?

    const size_t index = HB_OFFSET_TO_INDEX(offset);

                //mask的值与offset相关

    const unsigned long mask = HB_OFFSET_TO_MASK(offset);

 

    assert(hb->bits != NULL);

    assert((uintptr_t)obj >= hb->base);

    assert(index < hb->bitsLen / sizeof(*hb->bits));

    if (setBit) {

        if ((uintptr_t)obj > hb->max) {

            hb->max = (uintptr_t)obj;

        }

        if (returnOld) {

            unsigned long *p = hb->bits + index;

            const unsigned long word = *p;

            *p |= mask;

            return word & mask;

        } else {

            hb->bits[index] |= mask;

        }

    } else {

        hb->bits[index] &= ~mask;

    }

    return false;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值