kvm free chunk list

在kvm内部中在分配内饰时使用了free chunk list.其定义如下:

struct chunkStruct {
    long  size;     /*   当前chunk的大小,不包含该字段 */
    CHUNK next;     /*  指向下一个chunk */
};

如图所示:

在这里插入图片描述

这里需要注意的是:

  • size使用与常规对象头相同的格式存储,但是只使用最高的24位(见上文)。6个低位必须全部为零,字才能被识别为chunk头。

  • size不包括大小字段(headersize)本身,即,如果chunk的物理大小为3个字,则size的值为2

  • Chunk总是至少2个字(64位)长,因为这是分配新对象所需的最小大小(需要保存size和next字段)。小于此值的可用内存区域将自动与其他对象合并(从而为对象添加内碎片)。实际上,这种情况很少发生。

该结构是一个链表,如图:
在这里插入图片描述

分配chunk

分配chunk的方法为allocateFreeChunk.其代码如下:

static cell* allocateFreeChunk(long size)
{
    CHUNK thisChunk = FirstFreeChunk;
    CHUNK* nextChunkPtr = &FirstFreeChunk;
    cell* dataArea  = NIL;

    for (thisChunk = FirstFreeChunk, nextChunkPtr = &FirstFreeChunk;
         thisChunk != NULL;
         nextChunkPtr = &thisChunk->next, thisChunk = thisChunk->next) {

        /* Calculate how much bigger or smaller the */
        /* chunk is than the requested size  进行size的比较*/
        long overhead = SIZE(thisChunk->size) + HEADERSIZE - size; // SIZE(thisChunk->size) + HEADERSIZE 当前FirstFreeChunk的大小
        // overhead = 当前FirstFreeChunk 与 size(请求分配空间大小) 的差额.
        // 如果剩余空间大与1的话,则直接使用Chunk,大于1的目的是还需要分配对象头
        if (overhead > HEADERSIZE) {
        	// SIZE(thisChunk->size) + HEADERSIZE - size -  HEADERSIZE = SIZE(thisChunk->size)  - size
            thisChunk->size = (overhead - HEADERSIZE) << TYPEBITS;
            // 进行分配
            dataArea = (cell *)thisChunk + overhead;
            // 保存大小,不含对象头
            *dataArea = (size - HEADERSIZE) << TYPEBITS;
            return dataArea;
        } else if (overhead >= 0) {
            /*
             * 将整个Chunk 进行分配,如果剩余空间是在 [0,1] 之间
             */
            *nextChunkPtr = thisChunk->next;
            dataArea = (cell *)thisChunk;
            /* Store the size of the object in the object header 保存大小 */
            // size + overhead - HEADERSIZE = size + SIZE(thisChunk->size) + HEADERSIZE - size -HEADERSIZE = SIZE(thisChunk->size)
            *dataArea = (size + overhead - HEADERSIZE) << TYPEBITS; // 此时保存的大小就是当前Chunk的大小.
            return dataArea;
        }
    }
    /* If we got here, there was no chunk with enough memory available 如果到了这里,则意味着没有适会的chunk*/
    return NULL;
}

这里分三种情况:

  1. chunk 富足,满足size,且又剩余.此时分配前后的情况如图:

在这里插入图片描述

  1. chunk 刚好等于size.此时会将chunk 从free chunk list中移除.移除代码为:

    *nextChunkPtr = thisChunk->next;
    

    此时的情况如图:
    在这里插入图片描述

  2. chunk 与size间的剩余为1个cell,则此时会将该chunk 全部进行分配,但是会形成内碎片.此时的情况和第2种类似.只不过大小比size大了1.这里就不贴了

接下来我们会开始讲述kvm中的垃圾收集的实现.

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值