堆数据

本文介绍了一种内存分配算法,包括基本的内存块类(Block)和内存堆类(Heap)的设计与实现。Block类负责内存块的拆分与合并操作,Heap类则实现了内存分配、释放等功能,并考虑了连续可用内存的合并。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

伪代码,作记录用:

写的都只是思路上的代码,未运行过;

// @author Jave.Lin
// @date 2016-04-16 16:41
function getPOT(n:Number):Number
{
    var v:Number = 1;
    while (n < v) v <<= 1;
    return v;
}

// mem block
public class Block
{
    public var off_s:int;
    public var len:int;
    public var free:bool;

    public var nextBlock:Block;

    public function split(size:int):Bloack
    {
        if (free == false) return null;

        var pot_s:int = getPOT(size);
        if (len <= pot_s) return null;

        var r:Block = new Block();
        r.off_s = off_s;
        r.len = pot_s;
        r.free = true;
        r.nextBlock = this;

        off_s += pot_s;
        len -= pot_s;

        return r;
    }

    public function mergeNextBlock():Boolean
    {
        return merge(nextBlock);
    }

    public function merge(block:Bloack):Boolean
    {
        if (block == null || free == false) return false;

        len += block.len;
        nextBlock = block.nextBloack;
        block.nextBloack = null;

        return true;
    }
}

// mem block heap
public class Heap
{
    private var _byte:*Number = NULL;
    private var _size:int = 0;
    private var _blocks:Block[];

    public function Heap(pot_size:int)
    {
        allocBs(pot_size);
    }

    private var _lastCanUseContinueIdx:int = -1;
    private var _lastCanUseContinueSize:int = -1;

    public function freeBlock(b:Block):void
    {
        b.free = true;
    }

    // must be pot size
    public function getBlock(pot_s:int, os:int = 0):Block
    {
        for (var i:int = os; i < _size; ++i)
        {
            var b:Bloack = _blocks[i];

            if (b.free)
            {
                if (b.size >= pot_s)
                {
                    var sb:Block = b.split(pot_s);
                    if (sb != null)
                    {
                        _blocks[i] = sb;
                        var lb:Block = sb.nextBlock;
                        do
                        { _blocks[++i] = lb.nextBlock;
                        } while (lb.nextBlock);
                        return sb;
                    }
                    else
                    {
                        return b;
                    }
                }
                else
                {
                    if (_lastCanUseContinueIdx == -1)
                    {
                        _lastCanUseContinueIdx = i;
                        _lastCanUseContinueSize = b.len;
                    }
                    else
                    {
                        _lastCanUseContinueSize += b.len;
                    }
                    if (_lastCanUseContinueSize >= pot_s)
                    {
                        var lastB:Bloack = _blocks[_lastCanUseContinueIdx];
                        var subLen:int = i - _lastCanUseContinueIdx;
                        var mergeCount:int = subLen;
                        while (mergeCount > 0)
                        {
                            lastB.mergeNextBlock();
                            mergeCount--;
                        }
                        _blocks.split(i + 1, subLen);
                        return lastB;
                    }
                }
            }
            else
            {
                _lastCanUseContinueIdx = -1;
                _lastCanUseContinueSize = -1;
            }
        }

        raiseCap();

        return getBlock(size, _lastCanUseContinueIdx);
    }

    private function allocBs(pot_size:int):void
    {
        if (_size < pot_size)
        {
            var ps:int = _size;
            _size = pot_size;
            var b:Bloack = new Bloack();
            if (_byte == NULL)
            {
                _byte = alloc(_size * sizeof(Number));

                b.off_s = 0;
                b.len = _size;
                b.free = true;
                b.nextBlock = null;
                _blocks.push(b);
            }
            else
            {
                _byte = realloc(_byte, _size * sizeof(Number));

                b = new Block();
                b.off_s = ps;
                b.len = _size - ps;
                b.free = true;
                b.nextBloack = null;
                _blocks[_blocks.length - 1].nextBlock = b;
            }
        }
    }

    private function raiseCap():void
    {
        allocBs(getPOT(_size + 1);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值