?内存管理算法

该文章用作个人纪录。

简要介绍一下两种内存管理算法:

1.小内存管理算法

采用不断分割的方法对内存进行动态分配,分为初始化,分割,释放三个步骤,为了简洁起见,笔者直接放图:
头部 初始大内存块 尾部
头部 内存块 内存块 内存块 内存块 尾部

这是整体思想,通过对初始内存块的不断切割,最终形成了各个不同的内存块。

四个函数,第一个init:
头部 内存块 尾部

复制代码
/*sk
*ai
*ui
*ji
*ng
*/

void heap_init()
{

    heap_node *firstnode;
    //这行注释不要删除
    //命名不要随便改,不然有概率导致数组最后八个字节出现segmentation fault问题
    
    uint32_t start_heap ,end_heap;
    //get start address
    start_heap =(uint32_t) allheap;

    /*byte aligment*/
    if( (start_heap & aligment_byte) != 0){
        start_heap += aligment_byte ;
        start_heap &= ~aligment_byte;
        theheap.allsize -=  (size_t)(start_heap - (uint32_t)allheap);//byte aligment means move to high address,so sub it!
    }

    theheap.head.next = (heap_node *)start_heap;
    theheap.head.blocksize = (size_t)0;

    end_heap  = ( start_heap + (uint32_t)config_heap);


    /*byte aligment*/
    if( (end_heap & aligment_byte) != 0){
        end_heap += aligment_byte ;
        end_heap &= ~aligment_byte;
        theheap.allsize =  (size_t)(end_heap - start_heap );

    }
    theheap.tail = (heap_node*)end_heap;
    theheap.tail->blocksize  = 0; 
    theheap.tail->next =NULL;

    firstnode = (heap_node*)start_heap;
    firstnode->next = theheap.tail;

    firstnode->blocksize = theheap.allsize;

}

第二个malloc:
从头开始找_直到找到符合大小的内存块 头部 内存块 内存块 内存块 内存块 尾部
把初始化的内存链表模型作为空闲内存块建立的链表 在这条链表上找到符合条件的内存块 链表起始 结束 prev use new

这条链表上就是空闲内存块链表,内存块被使用就被踢出这条链表,被释放就加入这条链表,如果内存块大于要申请的大小,就把多余的部分切割,然后加入这条内存链表。

复制代码
void *heap_malloc(size_t wantsize)
{
    heap_node *prevnode;
    heap_node *usenode;

    heap_node *newnode;
    size_t aligmentrequisize;

    void *xReturn = NULL;

    if(wantsize <= 0 )
    {
        printf("Error in function: %s at line: %d\n", __func__, __LINE__); \
        exit(-1); 

    }

     
    wantsize += heapstructSize;
    if((wantsize & aligment_byte) != 0x00)
    {
        aligmentrequisize = aligment_byte - (wantsize & aligment_byte);
        wantsize += aligmentrequisize;
    }


    if((wantsize / arm_max_memory) != 0)
    {
        printf("Error in function: %s at line: %d\n", __func__, __LINE__); \
        exit(-1); 

    }
     
    //I will add the TaskSuspend function ,that make there be a atomic operation
    if(theheap.tail== NULL )
    {
        heap_init();
    }

    //

    prevnode = &theheap.head;
    usenode = theheap.head.next;
   

    //the next is valid ?

    while((usenode->blocksize) < wantsize )
    {
        prevnode = usenode;
        usenode = usenode ->next;
    }

    //

    if(usenode == theheap.tail)
    {
        printf("Error in function: %s at line: %d\n", __func__, __LINE__); \
        exit(-1);
    }
    
    xReturn = (void*)(((uint8_t*)usenode) + heapstructSize);

    prevnode->next = usenode->next ;
    /*apart it!*/
    if( (usenode->blocksize - wantsize) > MIN_size )
    {
        newnode = (void*)(((uint8_t*)usenode) + wantsize);

        newnode->blocksize = usenode->blocksize - wantsize;
        usenode->blocksize = wantsize;
        

        newnode->next = prevnode->next ;
        prevnode->next = newnode;
        
    }
   
    
    theheap.allsize-= usenode->blocksize;

    

    if(theheap.allsize < 0U)
    {
        printf("Error in function: %s at line: %d\n", __func__, __LINE__); \
        exit(-1);
    }
    
    usenode->next = NULL;

    // I will write the TaskResume



    

    if(usenode > theheap.tail)
    {

        printf("alheap : %d ,use: %d, tail: %d\n",allheap,usenode,theheap.tail);
        printf("fuck : %s at line: %d\n", __func__, __LINE__); 
        exit(-1);
    }

    
    return xReturn;


}

第三个free:
空闲内存块 空闲内存块 空闲内存块 Insert

直接插入即可。

复制代码
void heap_free(void *xret)
{
    uint8_t *xFree = (uint8_t*)xret;
    heap_node *xlink;

    if(xFree == NULL)
    {
        printf("Error in function: %s at line: %d\n", __func__, __LINE__); \
        exit(-1);
    }

    xFree -= heapstructSize;
    xlink = (void*)xFree;
    if(xlink->next != NULL)
    {
        printf("Error in function: %s at line: %d\n", __func__, __LINE__); \
        exit(-1);
    }

    // I will tasksuspend
    theheap.allsize += xlink->blocksize;
    InsertFreeBlock((heap_node*)xlink);
     
    // I will TaskResume


}

精髓在于InsertFreeBLOCK:
开始 prev next 结束 Insert ?
start B Insert D E end
后相邻 Insert E start B D end
前相邻 B D start Insert E end
可以只考虑最终结果 B E start Insert D end

如果前后相邻是相互独立的,那么互不影响,如果不独立,通过后,前的顺序可以得到前后都相邻的结果,因此该顺序正确。

复制代码
xInsertBlock->next = first_fitnode->next;
    first_fitnode->next = xInsertBlock;

    getaddr = (uint8_t*)xInsertBlock;
    if((getaddr + xInsertBlock->blocksize) == (uint8_t*)(xInsertBlock->next))
    {
      
        if(xInsertBlock->next != theheap.tail )
        {
            xInsertBlock->blocksize += xInsertBlock->next->blocksize;
            xInsertBlock->next = xInsertBlock->next->next;
        }
        else
        {
            xInsertBlock->next = theheap.tail;
        }
    }
    
    
    
    getaddr = (uint8_t*)first_fitnode;

    if((getaddr + first_fitnode->blocksize) == (uint8_t*) xInsertBlock)
    {
        first_fitnode->blocksize += xInsertBlock->blocksize;
        first_fitnode->next = xInsertBlock->next;
    }
相关推荐
萧西待水1 小时前
奥赛一本通 1447 靶形数独
算法·深度优先
梦帮科技3 小时前
AI 音乐产品的发布工程:验证门、数据发布、回滚与生产运维纪律
数据结构·数据库·架构·node.js·音视频·动态规划·推荐算法
西安栈上月明软件科技3 小时前
从 Linux 0.01 到 AI 开源:星图邻的开源实践
人工智能·自然语言处理·架构·开源·fastapi
泯泷3 小时前
那段文字是谁删的?Yjs 14 正式版之前,一套删除归属方案的实现与边界
前端·javascript·算法
hold?fish:palm4 小时前
34 合并K个升序链表
javascript·算法·链表
C++ 老炮儿的技术栈4 小时前
我们在设计tcp协议时,要传一个字符串过去,报文:头十长度十内容,是否要把‘\0‘也填入,长度是否包含‘\0‘
开发语言·数据结构·c++·mfc·c
传奇开心果编程5 小时前
【Rust入门练中学】第2课:变量、可变性与常量
开发语言·学习·rust
zr想努力5 小时前
从0开始配置Perforce4环境
开发语言
Navigator_Z6 小时前
LeetCode //C - 1252. Cells with Odd Values in a Matrix
c语言·算法·leetcode
Lynne3096 小时前
工业网络,到底该集中还是自治?
网络·架构·数据