IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 内存池原理及设计与实现 -> 正文阅读

[数据结构与算法]内存池原理及设计与实现

内存池原理及设计与实现

什么是内存池?

内存池就是将malloc和free进行封装,为了减少内存碎片、加快内存分配而设计出的一种内存分配方式。

内存池原理

伙伴算法

将内存以2的次方形式进行划分,2、4、8、16、32、64……,将申请分配的空间以最近的数值分配(大于申请空间),这种形式可以尽量减少内存碎片,浪费少量内存。
以下列方式实现内存块的覆盖:

  • 将大块内存( 2 n 2^n 2n)分为两个小块( 2 n ? 1 2^{n-1} 2n?1)内存
  • 将两块物理连续的内存( 2 n ? 1 2^{n-1} 2n?1)合并为一个大块内存( 2 n 2^n 2n)。

链表

这种方法就是使用链表将页连起来,对页进行管理。(释放时机不好掌控,释放位置不好确定,耗费内存)

  • 申请的空间大于等于页,则判定为大块内存,单独开辟存入大块内存链表;
  • 申请的空间小于页,则从现有页中进行分配(直接给出地址);

我设计的内存池

伙伴算法

  • 每个 2 n 2^n 2n级都创建一个链表进行管理,每个链表按照地址升序进行排序,每一个结构体中存储begin和end来表示该内存区间,end大于实际存储空间(相当于下一个空间的begin),这样方便小块合并。
  • 申请空间先在最近队列中寻找有无空闲节点,没有则依次向大一级队列拆分空间,到页还找不到则开辟空间,将申请的地址和结构体地址合并为key、value存放进红黑树,可用C++map。
  • 释放空间在红黑树中查找到对应的结构体,然后进行结构体设置,依次左右查看是否能合并。

链表

数据结构

  • 大块内存结构体
    typedef struct _MEMORY_LARGE {
    struct _MEMORY_LARGE *next;
    unsigned char data[0];
    } MEMORY_LARGE;
  1. 下一个节点
  2. 柔性数组(0长数组),存储实际数据。
  • 页结构体
    typedef struct _MEMORY_PAGE {
    int used;
    void *current; // current
    void *end; // rear + 1, address can’t use
    struct _MEMORY_PAGE *prev;
    struct _MEMORY_PAGE *next;
    unsigned char data[0];
    } MEMORY_PAGE;
  1. 被使用了几次
  2. 当前页未使用空间的起始地址
  3. 当前页的结束地址(大于实际可使用地址,+1)
  4. 上一页
  5. 下一页
  6. 存储实际数据。
  • 内存池结构体
    typedef struct _MEMORY_POOL {
    #ifdef INFO_FLAG
    FILE *info_fd;
    #endif
    int page_try;
    int page_num;
    int page_idle_num;
    int large_num;
    struct _MEMORY_PAGE *page_head;
    struct _MEMORY_PAGE *page_rear;
    struct _MEMORY_PAGE *page_current;
    struct _MEMORY_LARGE *large_head;
    } MEMORY_POOL;
  1. 信息文件fd
  2. 当前页尝试申请了几次空间(不成功),用于跳过当前页(3次不成功就不在这个页申请了)。
  3. 总页数
  4. 空闲页数
  5. 大块内存数
  6. 页链表头
  7. 页链表尾
  8. 从哪个页开始尝试申请空间
  9. 大块内存链表头

对外接口

  • MemoryPoolInit 对MEMORY_POOL对象进行初始化,可以指定预分配的页数。
  • MemoryPoolDestroy 对已经初始化的对象进行销毁。
  • MemoryPoolMalloc 对内存池对象申请空间。
  • MemoryPoolFree 对内存池对象分配的空间进行释放。

具体操作

  • MemoryPoolInit 调用MemoryLargeMalloc创建一个大块内存结构体当作大块内存链表的头结点(哨兵),便于后面链表指针的统一处理。先创建一页,然后按照指定页数或者默认页数(指定页数为0),调用MemoryPageAdd进行分配页。如果函数申请malloc过程中返回NULL则调用MemoryPoolDestroy销毁内存池。
  • MemoryPoolDestroy 遍历大块内存链表和页链表,并依次释放。
  • MemoryPoolMalloc 如果申请空间大于等于页的大小,则调用MemoryLargeMalloc申请大块内存空间。否则调用MemoryPageMalloc申请小块内存空间。
  • MemoryPoolFree 如果知道分配的内存大小,则可以知道分配的是大块内存还是小块内存,直接调用对应的处理函数即可MemoryLargeFree和MemoryPageFree。如果不知道(size为0,一般情况),先调用MemoryLargeFree再调用MemoryPageFree,效率很低。改进方法:1. 可以使用布隆过滤器来筛选出大部分不是大块内存的情况,可以直接调用MemoryPageFree,否则先调用MemoryLargeFree再调用MemoryPageFree。这种方法可以提高一定的效率。2. 可以使用红黑树来保存相关信息,以分配的地址为key,分配地址大小和分配地址对应的结构体地址为value。可以极大的提高效率。
  • MemoryLargeMalloc 直接malloc出sizeof(MEMORY_LARGE)+size大小的结点,插入到链表尾部,返回data首地址。
  • MemoryLargeFree 遍历每个结点找到data首地址相同的则释放并返回0,未找到则返回-1(表示不是大块内存空间)。
  • MemoryPageAdd 新增指定数量的页(malloc出sizeof(MEMORY_PAGE)+页的大小的结点),依次插入到链表尾部。总数增加,空闲数量增加。
  • MemoryPageDel 从页链表尾部开始删除指定数量的页。
  • MemoryPageMalloc 从当前指向的页开始尝试分配空间,如果该页的未分配空间不够则(尝试数增加)再尝试下一页,所有的页都无法分配则调用MmeoryPageAdd增加指定倍率的空间(当前数量,相当于空间*2),然后再进行分配。如果是最开始的当前页分配成功,直接将尝试次数归零。如果尝试次数等于3,则将page_current指向下一页。分配成功将分配页被使用次数加一。
  • MemoryPageFree 遍历每一页,查看data地址是否在当前页可使用的空间区间内。找到对应的页,将被使用次数减一。如果被使用次数等于0,则表示当前页是空页了,把该页从链表中抽出来并插入到链表尾部并将current指向data首地址,如果只有一个页就只将current指向data首地址就行。如果空闲率大于等于指定空闲率(0.75),则调用MemoryPageDel将页链表删除一半。

代码实现(链表)

memory_pool.h

/******************************************************************************
*
*  Copyright (C), 2001-2005, Huawei Tech. Co., Ltd.
*
*******************************************************************************
*  File Name     : memory_pool.h
*  Version       : Initial Draft
*  Author        : sst
*  Created       : 2021/7/22
*  Last Modified :
*  Description   : memory_pool.c header file
*  Function List :
*
*
*  History:
* 
*       1.  Date         : 2021/7/22
*           Author       : sst
*           Modification : Created file
*
******************************************************************************/
#ifndef __MEMORY_POOL_H__
#define __MEMORY_POOL_H__


#ifdef __cplusplus
#if __cplusplus
extern "C"{
#endif
#endif /* __cplusplus */

/*==============================================*
 *      include header files                    *
 *----------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
/*==============================================*
 *      constants or macros define              *
 *----------------------------------------------*/
#define MEMORY_POOL_PAGE_SIZE   4096    // large >= it, page < it
#define MEMORY_PAGE_NUM_DEF     1       // > 0, init create page count
#define MEMORY_POOL_ADD_RATE    1       // add page count = num_page * it
#define MEMORY_POOL_DEL_POINT   0.75    // delete point > num_page_idle / num_page
#define MEMORY_POOL_DEL_RATE    0.5     // delete count = num_page * it
#ifdef INFO_FLAG
#define LARGE_FREE -1
#define PAGE_FREE -2
#define PAGE_CRETE -3
#define PAGE_FREE_APPLY -4
#endif
/*==============================================*
 *      project-wide global variables           *
 *----------------------------------------------*/

/*==============================================*
 *      routines' or functions' implementations *
 *----------------------------------------------*/
typedef struct _MEMORY_LARGE {
    struct _MEMORY_LARGE *next;
    unsigned char data[0];
} MEMORY_LARGE;

typedef struct _MEMORY_PAGE {
    int used;
    void *current; // current
    void *end;     // rear + 1, address can't use
    struct _MEMORY_PAGE *prev;
    struct _MEMORY_PAGE *next;
    unsigned char data[0];
} MEMORY_PAGE;

typedef struct _MEMORY_POOL {
#ifdef INFO_FLAG
    FILE *info_fd;
#endif
    int page_try;
    int page_num;
    int page_idle_num;
    int large_num;
    struct _MEMORY_PAGE *page_head;
    struct _MEMORY_PAGE *page_rear;
    struct _MEMORY_PAGE *page_current;
    struct _MEMORY_LARGE *large_head;
} MEMORY_POOL;

#ifdef INFO_FLAG
extern void InfoClose(MEMORY_POOL *memory_pool);
extern void InfoOpen(MEMORY_POOL *memory_pool, const char *info_path);
extern void InfoWrite(MEMORY_POOL *memory_pool, void *data, int size);
#endif
extern int MemoryLargeFree(MEMORY_POOL *memory_pool, void *data);
extern void* MemoryLargeMalloc(MEMORY_POOL *memory_pool, int size);
extern int MemoryPageAdd(MEMORY_POOL *memory_pool, int count);
extern void MemoryPageDel(MEMORY_POOL *memory_pool, int count);
extern int MemoryPageFree(MEMORY_POOL *memory_pool, void *data);
extern void MemoryPageInit(MEMORY_PAGE *page);
extern void* MemoryPageMalloc(MEMORY_POOL *memory_pool, int size);
extern void MemoryPoolDestroy(MEMORY_POOL *memory_pool);
extern void MemoryPoolFree(MEMORY_POOL *memory_pool, void *data, int size);
extern MEMORY_POOL* MemoryPoolInit(int page);
extern void* MemoryPoolMalloc(MEMORY_POOL *memory_pool, int size);

#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* __cplusplus */


#endif /* __MEMORY_POOL_H__ */

memory_pool.c

#include "memory_pool.h"

void* MemoryPoolMalloc(MEMORY_POOL *memory_pool, int size) {
    if(size >= MEMORY_POOL_PAGE_SIZE) {
        return MemoryLargeMalloc(memory_pool, size);
    } else {
        return MemoryPageMalloc(memory_pool, size);
    }
}

void MemoryPoolFree(MEMORY_POOL *memory_pool, void *data, int size) {
    if(size) { // remember memory size
        if(size >= MEMORY_POOL_PAGE_SIZE) {
            if(MemoryLargeFree(memory_pool, data) == -1) {
                printf("free error, object doesn't in memory_pool\n");
                exit(-1);
            }
        } else {
            if(MemoryPageFree(memory_pool, data) == -1) {
                printf("free error, object doesn't in memory_pool\n");
                exit(-1);
            }
        }
    } else {
        if(MemoryLargeFree(memory_pool, data) == -1) {
            if(MemoryPageFree(memory_pool, data) == -1) {
                printf("free error, object doesn't in memory_pool\n");
                exit(-1);
            }
        }
    }
}

void* MemoryLargeMalloc(MEMORY_POOL *memory_pool, int size) {
    MEMORY_LARGE *large_new = 
        (MEMORY_LARGE*)malloc(sizeof(MEMORY_LARGE) + size);
    if(large_new == NULL) return NULL;
#ifdef INFO_FLAG
    InfoWrite(memory_pool, large_new->data, size);
#endif    
    ++memory_pool->large_num;
    large_new->next = memory_pool->large_head->next;
    memory_pool->large_head->next = large_new;
    return (void*)large_new->data;
}

int MemoryLargeFree(MEMORY_POOL *memory_pool, void *data) {
    MEMORY_LARGE *current = memory_pool->large_head, *large_delete;
    while(current->next != NULL) {
        if(data == current->next->data) {
            large_delete = current->next;
            current->next = large_delete->next;
#ifdef INFO_FLAG
            InfoWrite(memory_pool, large_delete->data, LARGE_FREE);
#endif        
            free(large_delete);
            --memory_pool->large_num;
            return 0;
        }
        current = current->next;
    }
    return -1;
}

void* MemoryPageMalloc(MEMORY_POOL *memory_pool, int size) {
    MEMORY_PAGE *page = memory_pool->page_current;
    while(1) {
        while(page) {
            if(page->current + size < page->end) {
                void *res = page->current;
#ifdef INFO_FLAG
                InfoWrite(memory_pool, res, size);
#endif                 
                if(page == memory_pool->page_current) {
                    memory_pool->page_try = 0;
                }
                if(!page->used) memory_pool->page_idle_num--;
                ++page->used;
                page->current += size;
                return res; 
            } else {
                ++memory_pool->page_try;
                if(memory_pool->page_try == 3) 
                    memory_pool->page_current = memory_pool->page_current->next;
            }
            page = page->next;
        }
        page = memory_pool->page_rear;
        if(MemoryPageAdd(memory_pool, 
                         memory_pool->page_num * MEMORY_POOL_ADD_RATE) == -1) 
            return NULL;
        page = page->next;
    }
    return NULL;
}

int MemoryPageFree(MEMORY_POOL *memory_pool, void *data) {
    MEMORY_PAGE *page = memory_pool->page_head;
    while(page) {
        if((unsigned long int)page->data <= (unsigned long int)data && 
            (unsigned long int)data < (unsigned long int)page->end) {
#ifdef INFO_FLAG
            InfoWrite(memory_pool, data, PAGE_FREE_APPLY);
#endif             
            --page->used;
            if(!page->used) {
                page->current = page->data;
                if(page->prev == NULL) {
                    if(page->next == NULL) return 0;
                    memory_pool->page_head = page->next;
                    page->next->prev = NULL;
                } else {
                    page->prev->next = page->next;
                    page->next->prev = page->prev;
                }
                if(memory_pool->page_current == page && 
                   page->next != NULL) {
                    memory_pool->page_current = page->next;
                }
                memory_pool->page_rear->next = page;
                page->prev = memory_pool->page_rear;
                page->next = NULL;
                memory_pool->page_rear = page;
                ++memory_pool->page_idle_num;

                while(MEMORY_POOL_DEL_POINT <= 
                      (1.0 * memory_pool->page_idle_num / memory_pool->page_num) &&
                      memory_pool->page_num > MEMORY_PAGE_NUM_DEF) {
                    MemoryPageDel(memory_pool, 
                                  memory_pool->page_num * MEMORY_POOL_DEL_RATE);
                }
            }
            return 0;
        }
        page = page->next;
    }
    return -1;
}

void MemoryPageInit(MEMORY_PAGE *page) {
    page->current = page->data;
    page->end = page->data + MEMORY_POOL_PAGE_SIZE;
    page->next = NULL;
    page->prev = NULL;
    page->used = 0;
}

void MemoryPageDel(MEMORY_POOL *memory_pool, int count) {
    MEMORY_PAGE *rear = memory_pool->page_rear, *wait_delete;
    memory_pool->page_num -= count;
    memory_pool->page_idle_num -= count;
    int i;
    for(i = 0; i < count; ++i) {
        wait_delete = rear;
        rear = rear->prev;
#ifdef INFO_FLAG
        InfoWrite(memory_pool, wait_delete->data, PAGE_FREE);
#endif 
        free(wait_delete);
    }
    rear->next = NULL;
    memory_pool->page_rear = rear;
}

int MemoryPageAdd(MEMORY_POOL *memory_pool, int count) {
    if(!count) return 0;
    int i;
    MEMORY_PAGE *prev = memory_pool->page_rear, *rear;
    for(i = 0; i < count; ++i) {
        rear = (MEMORY_PAGE*)malloc(sizeof(MEMORY_PAGE) + MEMORY_POOL_PAGE_SIZE);
        if(rear == NULL) goto error_add;
#ifdef INFO_FLAG
        InfoWrite(memory_pool, rear->data, PAGE_CRETE);
#endif
        MemoryPageInit(rear);
        prev->next = rear;
        rear->prev = prev;
        prev = rear;
    }
    rear->next = NULL;
    memory_pool->page_num += count;
    memory_pool->page_idle_num += count;
    memory_pool->page_rear = rear;
    return 0;
error_add:
    prev = memory_pool->page_rear->next;
    memory_pool->page_rear->next = NULL;
    while(prev != NULL) {
        rear = prev;
        prev = prev->next;
#ifdef INFO_FLAG
        InfoWrite(memory_pool, rear, PAGE_FREE);
#endif
        free(rear);
    }
    return -1;
}

void MemoryPoolDestroy(MEMORY_POOL *memory_pool) {
    MEMORY_LARGE *memory_large = memory_pool->large_head, *large_delete;
    while(memory_large != NULL) {
        large_delete = memory_large;
        memory_large = memory_large->next;
#ifdef INFO_FLAG
        InfoWrite(memory_pool, large_delete, LARGE_FREE);
#endif
        free(large_delete);
    }
    MEMORY_PAGE *memory_page = memory_pool->page_head, *page_delete;
    while(memory_page != NULL) {
        page_delete = memory_page;
        memory_page = memory_page->next;
#ifdef INFO_FLAG
        InfoWrite(memory_pool, page_delete, PAGE_FREE);
#endif
        free(page_delete);
    }
#ifdef INFO_FLAG
    InfoClose(memory_pool);
#endif
    free(memory_pool);
}

// init memory pool, page = 0 use default page count
MEMORY_POOL* MemoryPoolInit(int page) {
    MEMORY_POOL *memory_pool = (MEMORY_POOL*)malloc(sizeof(MEMORY_POOL));
#ifdef INFO_FLAG
    InfoOpen(memory_pool, "infomation.txt");
#endif
    // as guard
    memory_pool->large_head = (MEMORY_LARGE*)malloc(sizeof(MEMORY_LARGE));
    if(memory_pool->large_head == NULL) goto error_init;
#ifdef INFO_FLAG

#endif

    memory_pool->page_head = 
        (MEMORY_PAGE*)malloc(sizeof(MEMORY_PAGE) + MEMORY_POOL_PAGE_SIZE);
    if(memory_pool->page_head == NULL) goto error_init;

#ifdef INFO_FLAG
    InfoWrite(memory_pool, memory_pool->page_head->data, PAGE_CRETE);
#endif
    MemoryPageInit(memory_pool->page_head);
    memory_pool->page_rear = memory_pool->page_head;
    memory_pool->page_current = memory_pool->page_head;
    memory_pool->large_num = 0;
    memory_pool->page_num = 1;
    memory_pool->page_try = 0;
    if(page == 0) page = MEMORY_PAGE_NUM_DEF;
    if(MemoryPageAdd(memory_pool, page - 1) == -1) 
        goto error_init;
    memory_pool->page_idle_num = memory_pool->page_num;

    return memory_pool;
error_init:
    MemoryPoolDestroy(memory_pool);
    return NULL;
}

#ifdef INFO_FLAG
void InfoOpen(MEMORY_POOL *memory_pool, const char *info_path) {
    memory_pool->info_fd = fopen(info_path, "w");
    if(memory_pool->info_fd == NULL)
        perror("fopen error : ");
}

void InfoClose(MEMORY_POOL *memory_pool) {
    fclose(memory_pool->info_fd);
}

void InfoWrite(MEMORY_POOL *memory_pool, void *data, int size) {
    char buffer[1024];
    if(size >= MEMORY_POOL_PAGE_SIZE) {
        sprintf(buffer, "create large, data : %lx, size : %d\n", 
                (unsigned long int)data, size);
    } else if(size > 0) {
        sprintf(buffer, "apply page, data : %lx, size : %d\n", 
                (unsigned long int)data, size);
    } else if(size == 0) {
        sprintf(buffer, "create large, data : %lx, size : %d\n", 
                (unsigned long int)data, size);
    } else if(size == PAGE_CRETE) {
        sprintf(buffer, "create page, data : %lx, size : %d\n", 
                (unsigned long int)data, size);
    } else if(size == LARGE_FREE) {
        sprintf(buffer, "free large, data : %lx\n", (unsigned long int)data);
    } else if(size == PAGE_FREE) {
        sprintf(buffer, "free page, data : %lx\n", (unsigned long int)data);
    } else if(size == PAGE_FREE_APPLY) {
        sprintf(buffer, "free apply, data : %lx\n", (unsigned long int)data);
    }
    if(fwrite(buffer, strlen(buffer), 1, memory_pool->info_fd) == 0)
        perror("write error : ");
}
#endif

test_project.c

#include "lib/memory_pool.h"

#include <stdio.h>
#include <string.h>
#include <sys/time.h>

// spend time = current time - old time
// day + hours + minute + second + millisecond + mincrosecond + info
void TimeCurrentSpend(struct timeval *time_old, char *info)
{
    struct timeval now;
    gettimeofday(&now, NULL);
    if(now.tv_usec < time_old->tv_usec)
    {
        now.tv_sec--;
        now.tv_usec += 1000000;
    }
    time_t sec = now.tv_sec - time_old->tv_sec;
    char info_old[strlen(info) + 1];
    strcpy(info_old, info);
    sprintf(info, "%2ldd,%2ldh,%2ldm,%2lds,%4ldms,%4ldus :  %s",
        sec /8640,                                  // day
        (sec / 360) % 24,                           // hours
        (sec / 60) % 60,                            // minute
        sec % 60,                                   // second
        (now.tv_usec - time_old->tv_usec) / 1000,    // millisecond
        (now.tv_usec - time_old->tv_usec) % 1000,    // mincrosecond
        info_old);                                  // info
}

void WorkTime(void (*work)(void *args), void *args, char *info) {
    char time_buffer[1024];
    struct timeval old;
    gettimeofday(&old, NULL);

    work(args);

    sprintf(time_buffer, "%s", info);
    TimeCurrentSpend(&old, time_buffer);
    printf("%s", time_buffer);
}

void TestMemoryPoolLargeMallocPage(void *args) {
    const int n = *(int*)args;
    MEMORY_POOL *memory_pool = MemoryPoolInit(0);

    int i, *data[n];
    for(i = 0; i < n; ++i) {
        data[i] = (int*)MemoryPoolMalloc(memory_pool, sizeof(int));
        *data[i] = i;
//        printf("data[%d] = %d\n", i, *data[i]);
    }

    for(i = 0; i < n; ++i) {
//        printf("free data[%d]\n", i);
        MemoryPoolFree(memory_pool, data[i], 0);
    }

    MemoryPoolDestroy(memory_pool);
}

void TestMemoryPoolMallocPage(void *args) {
    const int n = *(int*)args;
    MEMORY_POOL *memory_pool = MemoryPoolInit(0);

    int i, *data;
    for(i = 0; i < n; ++i) {
        data = (int*)MemoryPoolMalloc(memory_pool, sizeof(int));
        *data = i;
//        printf("%d\n", *data);
        MemoryPoolFree(memory_pool, data, sizeof(int));
    }

    MemoryPoolDestroy(memory_pool);
}


void TestLargeMalloc(void *args) {
    const int n = *(int*)args;
    int i, *data[n];
    for(i = 0; i < n; ++i) {
        data[i] = (int*)malloc(sizeof(int));
        *data[i] = i;
//        printf("data[%d] = %d\n", i, *data[i]);
    }

    for(i = 0; i < n; ++i) {
//        printf("free data[%d]\n", i);
        free(data[i]);
    }
}

void TestMalloc(void *args) {
    const int n = *(int*)args;
    int i, *data;
    for(i = 0; i < n; ++i) {
        data = (int*)malloc(sizeof(int));
        *data = i;
//        printf("%d\n", *data);
        free(data);
    }
}


int main(int argc, char **argv)
{
    /*
    MEMORY_POOL *memory_pool = MemoryPoolInit(0);
    while(1) {
        int i, j, *data[1024 * 5], *large[1024];
        for(i = 0; i < 1024; ++i) {
            large[i] = (int*)MemoryPoolMalloc(memory_pool, sizeof(int) * 1024 * 5);
        }
        for(i = 0; i < 1024 * 5; ++i) {
            for(j = 0; j < 1024; ++j) {
                large[j][i] = i;
//                printf("large[%d][%d] = %d\n", j, i, large[j][i]);
            }
            data[i] = (int*)MemoryPoolMalloc(memory_pool, sizeof(int));
            *data[i] = i;
            printf("data[%d] = %d\n", i, *data[i]);
        }

        for(i = 0; i < 1024 * 5; ++i) {
            printf("free data[%d]\n", i);
            MemoryPoolFree(memory_pool, data[i], 0);
        }

        for(i = 0; i < 1024; ++i) {
            printf("free large[%d]\n", i);
            MemoryPoolFree(memory_pool, large[i], 0);
        }

        char in;
        in = getchar();
        if(in == 'q') break;
    }
    MemoryPoolDestroy(memory_pool);
    */
    char info[1024];
    int n = 1e6;
    sprintf(info, "memory pool large malloc page test\n");
    WorkTime(TestMemoryPoolLargeMallocPage, (void*)&n, info);
    sprintf(info, "malloc large malloc test\n");
    WorkTime(TestLargeMalloc, (void*)&n, info);

    sprintf(info, "memory pool malloc page test\n");
    WorkTime(TestMemoryPoolMallocPage, (void*)&n, info);
    sprintf(info, "malloc test\n");
    WorkTime(TestMalloc, (void*)&n, info);
    
    return 0;
}

效果测试

  • 使用内存池和malloc同时开辟大量的空间,内存池效果较好(取消代码优化)
    请添加图片描述
  • 使用内存池和malloc开辟一个空间free一个空间,malloc效果较好。(取消代码优化)
    请添加图片描述
  • 保留代码优化
    请添加图片描述
  • 开辟大量空间时,malloc存在寻址的操作,有碎片化的话,malloc肯定会影响性能,所以内存池较快。
  • 开辟一个空间释放一个空间,内存池会进行额外的操作,所以malloc较快。这还是我测试时使用了MemoryPoolFree最后一个参数,要不然还要判断是不是大块存储空间,就更慢了。
  • 不过,内存池用来判断内存泄漏这是malloc办不到的,开启info写文件也会影响内存池性能,所以我设置了debug的时候define INFO_FLAG就可以开启info。
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-07-27 16:29:50  更:2021-07-27 16:31:04 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 17:34:02-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码