色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

內(nèi)存池的使用場景

科技綠洲 ? 來源:Linux開發(fā)架構(gòu)之路 ? 作者:Linux開發(fā)架構(gòu)之路 ? 2023-11-10 17:19 ? 次閱讀

為什么要用內(nèi)存池

為什么要用內(nèi)存池?首先,在7 * 24h的服務(wù)器中如果不使用內(nèi)存池,而使用malloc和free,那么就非常容易產(chǎn)生內(nèi)存碎片,早晚都會申請內(nèi)存失??;并且在比較復(fù)雜的代碼或者繼承的屎山中,非常容易出現(xiàn)內(nèi)存泄漏導(dǎo)致mmo的問題。

為了解決這兩個問題,內(nèi)存池就應(yīng)運而生了。內(nèi)存池預(yù)先分配一大塊內(nèi)存來做一個內(nèi)存池,業(yè)務(wù)中的內(nèi)存分配和釋放都由這個內(nèi)存池來管理,內(nèi)存池內(nèi)的內(nèi)存不足時其內(nèi)部會自己申請。所以內(nèi)存碎片的問題就交由內(nèi)存池的算法來優(yōu)化,而內(nèi)存泄漏的問題只需要遵守內(nèi)存池提供的api,就非常容易避免內(nèi)存泄漏了。

即使出現(xiàn)了內(nèi)存泄漏,排查的思路也很清晰。1.檢查是不是內(nèi)存池的問題;2.如果不是內(nèi)存池的問題,就檢查是不是第三方庫的內(nèi)存泄漏。

內(nèi)存池的使用場景

  1. 全局內(nèi)存池
  2. 一個連接一個內(nèi)存池(本文實現(xiàn)這個場景的內(nèi)存池)

設(shè)計一個內(nèi)存池

總體介紹

由于本文是一個連接一個內(nèi)存池,所以后續(xù)介紹和代碼都是以4k為分界線,大于4k的我們認(rèn)為是大塊內(nèi)存;小于4k的我們認(rèn)為是小塊內(nèi)存。并且注意這里的4k,并不是嚴(yán)格遵照4096,而是在描述上,用4k比較好描述。

在真正使用內(nèi)存之前,內(nèi)存池提前分配一定數(shù)量且大小相等的內(nèi)存塊以作備用,當(dāng)真正被用戶調(diào)用api分配內(nèi)存的時候,直接從內(nèi)存塊中獲取內(nèi)存(指小塊內(nèi)存),當(dāng)內(nèi)存塊不夠用了,再有內(nèi)存池取申請新的內(nèi)存塊。而如果是需要大塊內(nèi)存,則內(nèi)存池直接申請大塊內(nèi)存再返回給用戶。

內(nèi)存池:就是將這些提前申請的內(nèi)存塊組織管理起來的數(shù)據(jù)結(jié)構(gòu),內(nèi)存池實現(xiàn)原理主要分為分配,回收,擴容三部分。

內(nèi)存池原理之小塊內(nèi)存:分配=> 內(nèi)存池預(yù)申請一塊4k的內(nèi)存塊,這里稱為block,即block=4k內(nèi)存塊。當(dāng)用戶向內(nèi)存池申請內(nèi)存size小于4k時,內(nèi)存池從block的空間中劃分出去size空間,當(dāng)再有新申請時,再劃分出去。擴容=> 直到block中的剩余空間不足以分配size大小,那么此時內(nèi)存池會再次申請一塊block,再從新的block中劃分size空間給用戶?;厥?> 每一次申請小內(nèi)存,都會在對應(yīng)的block中引用計數(shù)加1,每一次釋放小內(nèi)存時,都會在block中引用計數(shù)減1,只有當(dāng)引用計數(shù)為零的時候,才會回收block使他重新成為空閑空間,以便重復(fù)利用空間。這樣,內(nèi)存池避免頻繁向內(nèi)核申請/釋放內(nèi)存,從而提高系統(tǒng)性能。

內(nèi)存池原理之大塊內(nèi)存:分配=> 因為大塊內(nèi)存是大于4k的,所以內(nèi)存池不預(yù)先申請內(nèi)存,也就是用戶申請的時候,內(nèi)存池再申請內(nèi)存,然后返回給用戶。擴容=> 大塊內(nèi)存不存在擴容?;厥?> 對于大塊內(nèi)存來說,回收就直接free掉即可。

上面理論講完了,下面來介紹如何管理小塊內(nèi)存和大塊內(nèi)存。

小塊內(nèi)存的分配與管理

在創(chuàng)建內(nèi)存池的時候,會預(yù)先申請一塊4k的內(nèi)存,并且在起始處將pool的結(jié)構(gòu)體和node的結(jié)構(gòu)體放進去,從last開始一直到end都是空閑內(nèi)存,中間的區(qū)域就用來存儲小塊內(nèi)存。每一次mp_malloc,就將last指針后移,直到 e n d ? l a s t < s i z e end - last < size end?last

初始狀態(tài)

圖片

分配內(nèi)存

圖片

擴容

圖片

大塊內(nèi)存的分配與管理

對于大塊內(nèi)存,前面已經(jīng)說了,用戶申請的時候,內(nèi)存池才申請

申請一塊大內(nèi)存

圖片

再申請一塊大內(nèi)存

圖片

內(nèi)存池代碼實現(xiàn)

向外提供的api

  • mp_create_pool:創(chuàng)建一個線程池,其核心是創(chuàng)建struct mp_pool_s這個結(jié)構(gòu)體,并申請4k內(nèi)存,將各個指針指向上文初始狀態(tài)的圖一樣。
  • mp_destroy_pool:銷毀內(nèi)存池,遍歷小塊結(jié)構(gòu)體和大塊結(jié)構(gòu)體,進行free釋放內(nèi)存
  • mp_malloc:提供給用戶申請內(nèi)存的api
  • mp_calloc:通過mp_malloc申請內(nèi)存后置零,相當(dāng)于calloc
  • mp_free:釋放由mp_malloc返回的內(nèi)存
  • mp_reset_pool:將block的last置為初始狀態(tài),銷毀所有大塊內(nèi)存
  • monitor_mp_poll:監(jiān)控內(nèi)存池狀態(tài)
struct mp_pool_s *mp_create_pool(size_t size);

void mp_destroy_pool(struct mp_pool_s *pool);

void *mp_malloc(struct mp_pool_s *pool, size_t size);

void *mp_calloc(struct mp_pool_s *pool, size_t size);

void mp_free(struct mp_pool_s *pool, void *p);

void mp_reset_pool(struct mp_pool_s *pool);

void monitor_mp_poll(struct mp_pool_s *pool, char *tk);

相關(guān)結(jié)構(gòu)體的定義

mp_pool_s 就是整個內(nèi)存池的管理結(jié)構(gòu),我們做的內(nèi)存池是一個連接一個內(nèi)存池,所以對于整個程序而言,內(nèi)存池對象是有很多個的。

可能讀者會有疑問,有了head,為什么還有current,是因為如果一個block剩余空間小于size超過一定次數(shù)后,將current指向下一個block,這樣就加快內(nèi)存分配效率,減少遍歷次數(shù)。

//每4k一block結(jié)點
struct mp_node_s {
    unsigned char *end;//塊的結(jié)尾
    unsigned char *last;//使用到哪了
    struct mp_node_s *next;//鏈表
    int quote;//引用計數(shù)
    int failed;//失效次數(shù)
};

struct mp_large_s {
    struct mp_large_s *next;//鏈表
    int size;//alloc的大小
    void *alloc;//大塊內(nèi)存的起始地址
};

struct mp_pool_s {
    struct mp_large_s *large;
    struct mp_node_s *head;
    struct mp_node_s *current;
};

內(nèi)存對齊

訪問速度是內(nèi)存對齊的原因之一,另外一個原因是某些平臺(arm)不支持未內(nèi)存對齊的訪問

在4k里面劃分內(nèi)存,那么必然有很多地方是不對齊的,所以這里提供兩個內(nèi)存對齊的函數(shù)。那么為什么要內(nèi)存對齊呢?其一:提高訪問速度;其二:某些平臺arm不支持未對其的內(nèi)存訪問,會出錯。

#define mp_align(n, alignment) (((n)+(alignment-1)) & ~(alignment-1))
#define mp_align_ptr(p, alignment) (void *)((((size_t)p)+(alignment-1)) & ~(alignment-1))

創(chuàng)建與銷毀內(nèi)存池

創(chuàng)建一個線程池,其核心是創(chuàng)建struct mp_pool_s這個結(jié)構(gòu)體,并申請4k內(nèi)存,將各個指針指向上文初始狀態(tài)的圖一樣。
銷毀內(nèi)存池,遍歷小塊結(jié)構(gòu)體和大塊結(jié)構(gòu)體,進行free釋放內(nèi)存。

//創(chuàng)建內(nèi)存池
struct mp_pool_s *mp_create_pool(size_t size) {
    struct mp_pool_s *pool;
    if (size < PAGE_SIZE || size % PAGE_SIZE != 0) {
        size = PAGE_SIZE;
    }
    //分配4k以上不用malloc,用posix_memalign
    /*
        int posix_memalign (void **memptr, size_t alignment, size_t size);
     */

    int ret = posix_memalign((void **) &pool, MP_ALIGNMENT, size); //4K + mp_pool_s
    if (ret) {
        return NULL;
    }
    pool- >large = NULL;
    pool- >current = pool- >head = (unsigned char *) pool + sizeof(struct mp_pool_s);
    pool- >head- >last = (unsigned char *) pool + sizeof(struct mp_pool_s) + sizeof(struct mp_node_s);
    pool- >head- >end = (unsigned char *) pool + PAGE_SIZE;
    pool- >head- >failed = 0;

    return pool;
}

//銷毀內(nèi)存池
void mp_destroy_pool(struct mp_pool_s *pool) {
    struct mp_large_s *large;
    for (large = pool- >large; large; large = large- >next) {
        if (large- >alloc) {
            free(large- >alloc);
        }
    }

    struct mp_node_s *cur, *next;
    cur = pool- >head- >next;

    while (cur) {
        next = cur- >next;
        free(cur);
        cur = next;
    }
    free(pool);
}

圖片

提供給用戶的內(nèi)存申請api

申請的內(nèi)存以size做區(qū)分,如果大于4k就分配大塊內(nèi)存,小于4k就去block里面劃分。

//分配內(nèi)存
void *mp_malloc(struct mp_pool_s *pool, size_t size) {
    if (size <= 0) {
        return NULL;
    }
    if (size > PAGE_SIZE - sizeof(struct mp_node_s)) {
        //large
        return mp_malloc_large(pool, size);
    }
    else {
        //small
        unsigned char *mem_addr = NULL;
        struct mp_node_s *cur = NULL;
        cur = pool- >current;
        while (cur) {
            mem_addr = mp_align_ptr(cur- >last, MP_ALIGNMENT);
            if (cur- >end - mem_addr >= size) {
                cur- >quote++;//引用+1
                cur- >last = mem_addr + size;
                return mem_addr;
            }
            else {
                cur = cur- >next;
            }
        }
        return mp_malloc_block(pool, size);// open new space
    }
}
void *mp_calloc(struct mp_pool_s *pool, size_t size) {
    void *mem_addr = mp_malloc(pool, size);
    if (mem_addr) {
        memset(mem_addr, 0, size);
    }
    return mem_addr;
}

小塊內(nèi)存block擴容

所有的block都 e n d ? l a s t < s i z e end - last < size end?last

//new block 4k
void *mp_malloc_block(struct mp_pool_s *pool, size_t size) {
    unsigned char *block;
    int ret = posix_memalign((void **) &block, MP_ALIGNMENT, PAGE_SIZE); //4K
    if (ret) {
        return NULL;
    }
    struct mp_node_s *new_node = (struct mp_node_s *) block;
    new_node- >end = block + PAGE_SIZE;
    new_node- >next = NULL;

    unsigned char *ret_addr = mp_align_ptr(block + sizeof(struct mp_node_s), MP_ALIGNMENT);

    new_node- >last = ret_addr + size;
    new_node- >quote++;

    struct mp_node_s *current = pool- >current;
    struct mp_node_s *cur = NULL;

    for (cur = current; cur- >next; cur = cur- >next) {
        if (cur- >failed++ > 4) {
            current = cur- >next;
        }
    }
    //now cur = last node
    cur- >next = new_node;
    pool- >current = current;
    return ret_addr;
}

分配大塊內(nèi)存

//size >4k
void *mp_malloc_large(struct mp_pool_s *pool, size_t size) {
    unsigned char *big_addr;
    int ret = posix_memalign((void **) &big_addr, MP_ALIGNMENT, size); //size
    if (ret) {
        return NULL;
    }

    struct mp_large_s *large;
    //released struct large resume
    int n = 0;
    for (large = pool- >large; large; large = large- >next) {
        if (large- >alloc == NULL) {
            large- >size = size;
            large- >alloc = big_addr;
            return big_addr;
        }
        if (n++ > 3) {
            break;// 為了避免過多的遍歷,限制次數(shù)
        }
    }
    large = mp_malloc(pool, sizeof(struct mp_large_s));
    if (large == NULL) {
        free(big_addr);
        return NULL;
    }
    large- >size = size;
    large- >alloc = big_addr;
    large- >next = pool- >large;
    pool- >large = large;
    return big_addr;
}

釋放內(nèi)存

如果是大塊內(nèi)存,找到之后直接釋放;如果是小塊內(nèi)存,將引用計數(shù)減1,如果引用計數(shù)為0則重置last。

//釋放內(nèi)存
void mp_free(struct mp_pool_s *pool, void *p) {
    struct mp_large_s *large;
    for (large = pool- >large; large; large = large- >next) {//大塊
        if (p == large- >alloc) {
            free(large- >alloc);
            large- >size = 0;
            large- >alloc = NULL;
            return;
        }
    }
    //小塊 引用-1
    struct mp_node_s *cur = NULL;
    for (cur = pool- >head; cur; cur = cur- >next) {
//        printf("cur:%p   p:%p   end:%pn", (unsigned char *) cur, (unsigned char *) p, (unsigned char *) cur- >end);
        if ((unsigned char *) cur <= (unsigned char *) p && (unsigned char *) p <= (unsigned char *) cur- >end) {
            cur- >quote--;
            if (cur- >quote == 0) {
                if (cur == pool- >head) {
                    pool- >head- >last = (unsigned char *) pool + sizeof(struct mp_pool_s) + sizeof(struct mp_node_s);
                }
                else {
                    cur- >last = (unsigned char *) cur + sizeof(struct mp_node_s);
                }
                cur- >failed = 0;
                pool- >current = pool- >head;
            }
            return;
        }
    }
}

內(nèi)存池測試

//
// Created by 68725 on 2022/7/26.
//
#include < stdlib.h >
#include < stdio.h >
#include < string.h >

#define PAGE_SIZE 4096
#define MP_ALIGNMENT 16
#define mp_align(n, alignment) (((n)+(alignment-1)) & ~(alignment-1))
#define mp_align_ptr(p, alignment) (void *)((((size_t)p)+(alignment-1)) & ~(alignment-1))

//每4k一block結(jié)點
struct mp_node_s {
    unsigned char *end;//塊的結(jié)尾
    unsigned char *last;//使用到哪了
    struct mp_node_s *next;//鏈表
    int quote;//引用計數(shù)
    int failed;//失效次數(shù)
};

struct mp_large_s {
    struct mp_large_s *next;//鏈表
    int size;//alloc的大小
    void *alloc;//大塊內(nèi)存的起始地址
};

struct mp_pool_s {
    struct mp_large_s *large;
    struct mp_node_s *head;
    struct mp_node_s *current;
};

struct mp_pool_s *mp_create_pool(size_t size);

void mp_destroy_pool(struct mp_pool_s *pool);

void *mp_malloc(struct mp_pool_s *pool, size_t size);

void *mp_calloc(struct mp_pool_s *pool, size_t size);

void mp_free(struct mp_pool_s *pool, void *p);

void mp_reset_pool(struct mp_pool_s *pool);

void monitor_mp_poll(struct mp_pool_s *pool, char *tk);


void mp_reset_pool(struct mp_pool_s *pool) {
    struct mp_node_s *cur;
    struct mp_large_s *large;

    for (large = pool- >large; large; large = large- >next) {
        if (large- >alloc) {
            free(large- >alloc);
        }
    }

    pool- >large = NULL;
    pool- >current = pool- >head;
    for (cur = pool- >head; cur; cur = cur- >next) {
        cur- >last = (unsigned char *) cur + sizeof(struct mp_node_s);
        cur- >failed = 0;
        cur- >quote = 0;
    }
}

//創(chuàng)建內(nèi)存池
struct mp_pool_s *mp_create_pool(size_t size) {
    struct mp_pool_s *pool;
    if (size < PAGE_SIZE || size % PAGE_SIZE != 0) {
        size = PAGE_SIZE;
    }
    //分配4k以上不用malloc,用posix_memalign
    /*
        int posix_memalign (void **memptr, size_t alignment, size_t size);
     */

    int ret = posix_memalign((void **) &pool, MP_ALIGNMENT, size); //4K + mp_pool_s
    if (ret) {
        return NULL;
    }
    pool- >large = NULL;
    pool- >current = pool- >head = (unsigned char *) pool + sizeof(struct mp_pool_s);
    pool- >head- >last = (unsigned char *) pool + sizeof(struct mp_pool_s) + sizeof(struct mp_node_s);
    pool- >head- >end = (unsigned char *) pool + PAGE_SIZE;
    pool- >head- >failed = 0;

    return pool;
}

//銷毀內(nèi)存池
void mp_destroy_pool(struct mp_pool_s *pool) {
    struct mp_large_s *large;
    for (large = pool- >large; large; large = large- >next) {
        if (large- >alloc) {
            free(large- >alloc);
        }
    }

    struct mp_node_s *cur, *next;
    cur = pool- >head- >next;

    while (cur) {
        next = cur- >next;
        free(cur);
        cur = next;
    }
    free(pool);
}

//size >4k
void *mp_malloc_large(struct mp_pool_s *pool, size_t size) {
    unsigned char *big_addr;
    int ret = posix_memalign((void **) &big_addr, MP_ALIGNMENT, size); //size
    if (ret) {
        return NULL;
    }

    struct mp_large_s *large;
    //released struct large resume
    int n = 0;
    for (large = pool- >large; large; large = large- >next) {
        if (large- >alloc == NULL) {
            large- >size = size;
            large- >alloc = big_addr;
            return big_addr;
        }
        if (n++ > 3) {
            break;// 為了避免過多的遍歷,限制次數(shù)
        }
    }
    large = mp_malloc(pool, sizeof(struct mp_large_s));
    if (large == NULL) {
        free(big_addr);
        return NULL;
    }
    large- >size = size;
    large- >alloc = big_addr;
    large- >next = pool- >large;
    pool- >large = large;
    return big_addr;
}

//new block 4k
void *mp_malloc_block(struct mp_pool_s *pool, size_t size) {
    unsigned char *block;
    int ret = posix_memalign((void **) &block, MP_ALIGNMENT, PAGE_SIZE); //4K
    if (ret) {
        return NULL;
    }
    struct mp_node_s *new_node = (struct mp_node_s *) block;
    new_node- >end = block + PAGE_SIZE;
    new_node- >next = NULL;

    unsigned char *ret_addr = mp_align_ptr(block + sizeof(struct mp_node_s), MP_ALIGNMENT);

    new_node- >last = ret_addr + size;
    new_node- >quote++;

    struct mp_node_s *current = pool- >current;
    struct mp_node_s *cur = NULL;

    for (cur = current; cur- >next; cur = cur- >next) {
        if (cur- >failed++ > 4) {
            current = cur- >next;
        }
    }
    //now cur = last node
    cur- >next = new_node;
    pool- >current = current;
    return ret_addr;
}

//分配內(nèi)存
void *mp_malloc(struct mp_pool_s *pool, size_t size) {
    if (size <= 0) {
        return NULL;
    }
    if (size > PAGE_SIZE - sizeof(struct mp_node_s)) {
        //large
        return mp_malloc_large(pool, size);
    }
    else {
        //small
        unsigned char *mem_addr = NULL;
        struct mp_node_s *cur = NULL;
        cur = pool- >current;
        while (cur) {
            mem_addr = mp_align_ptr(cur- >last, MP_ALIGNMENT);
            if (cur- >end - mem_addr >= size) {
                cur- >quote++;//引用+1
                cur- >last = mem_addr + size;
                return mem_addr;
            }
            else {
                cur = cur- >next;
            }
        }
        return mp_malloc_block(pool, size);// open new space
    }
}

void *mp_calloc(struct mp_pool_s *pool, size_t size) {
    void *mem_addr = mp_malloc(pool, size);
    if (mem_addr) {
        memset(mem_addr, 0, size);
    }
    return mem_addr;
}

//釋放內(nèi)存
void mp_free(struct mp_pool_s *pool, void *p) {
    struct mp_large_s *large;
    for (large = pool- >large; large; large = large- >next) {//大塊
        if (p == large- >alloc) {
            free(large- >alloc);
            large- >size = 0;
            large- >alloc = NULL;
            return;
        }
    }
    //小塊 引用-1
    struct mp_node_s *cur = NULL;
    for (cur = pool- >head; cur; cur = cur- >next) {
//        printf("cur:%p   p:%p   end:%pn", (unsigned char *) cur, (unsigned char *) p, (unsigned char *) cur- >end);
        if ((unsigned char *) cur <= (unsigned char *) p && (unsigned char *) p <= (unsigned char *) cur- >end) {
            cur- >quote--;
            if (cur- >quote == 0) {
                if (cur == pool- >head) {
                    pool- >head- >last = (unsigned char *) pool + sizeof(struct mp_pool_s) + sizeof(struct mp_node_s);
                }
                else {
                    cur- >last = (unsigned char *) cur + sizeof(struct mp_node_s);
                }
                cur- >failed = 0;
                pool- >current = pool- >head;
            }
            return;
        }
    }
}

void monitor_mp_poll(struct mp_pool_s *pool, char *tk) {
    printf("rnrn------start monitor poll------%srnrn", tk);
    struct mp_node_s *head = NULL;
    int i = 0;
    for (head = pool- >head; head; head = head- >next) {
        i++;
        if (pool- >current == head) {
            printf("current== >第%d塊n", i);
        }
        if (i == 1) {
            printf("第%02d塊small block  已使用:%4ld  剩余空間:%4ld  引用:%4d  failed:%4dn", i,
                   (unsigned char *) head- >last - (unsigned char *) pool,
                   head- >end - head- >last, head- >quote, head- >failed);
        }
        else {
            printf("第%02d塊small block  已使用:%4ld  剩余空間:%4ld  引用:%4d  failed:%4dn", i,
                   (unsigned char *) head- >last - (unsigned char *) head,
                   head- >end - head- >last, head- >quote, head- >failed);
        }
    }
    struct mp_large_s *large;
    i = 0;
    for (large = pool- >large; large; large = large- >next) {
        i++;
        if (large- >alloc != NULL) {
            printf("第%d塊large block  size=%dn", i, large- >size);
        }
    }
    printf("rnrn------stop monitor poll------rnrn");
}



int main() {
    struct mp_pool_s *p = mp_create_pool(PAGE_SIZE);
    monitor_mp_poll(p, "create memory pool");
#if 0
    printf("mp_align(5, %d): %d, mp_align(17, %d): %dn", MP_ALIGNMENT, mp_align(5, MP_ALIGNMENT), MP_ALIGNMENT,
           mp_align(17, MP_ALIGNMENT));
    printf("mp_align_ptr(p- >current, %d): %p, p- >current: %pn", MP_ALIGNMENT, mp_align_ptr(p- >current, MP_ALIGNMENT),
           p- >current);
#endif
    void *mp[30];
    int i;
    for (i = 0; i < 30; i++) {
        mp[i] = mp_malloc(p, 512);
    }
    monitor_mp_poll(p, "申請512字節(jié)30個");

    for (i = 0; i < 30; i++) {
        mp_free(p, mp[i]);
    }
    monitor_mp_poll(p, "銷毀512字節(jié)30個");

    int j;
    for (i = 0; i < 50; i++) {
        char *pp = mp_calloc(p, 32);
        for (j = 0; j < 32; j++) {
            if (pp[j]) {
                printf("calloc wrongn");
                exit(-1);
            }
        }
    }
    monitor_mp_poll(p, "申請32字節(jié)50個");

    for (i = 0; i < 50; i++) {
        char *pp = mp_malloc(p, 3);
    }
    monitor_mp_poll(p, "申請3字節(jié)50個");


    void *pp[10];
    for (i = 0; i < 10; i++) {
        pp[i] = mp_malloc(p, 5120);
    }
    monitor_mp_poll(p, "申請大內(nèi)存5120字節(jié)10個");

    for (i = 0; i < 10; i++) {
        mp_free(p, pp[i]);
    }
    monitor_mp_poll(p, "銷毀大內(nèi)存5120字節(jié)10個");

    mp_reset_pool(p);
    monitor_mp_poll(p, "reset pool");

    for (i = 0; i < 100; i++) {
        void *s = mp_malloc(p, 256);
    }
    monitor_mp_poll(p, "申請256字節(jié)100個");

    mp_destroy_pool(p);
    return 0;
}

圖片

nginx內(nèi)存池對比分析

相關(guān)結(jié)構(gòu)體定義對比

圖片

創(chuàng)建內(nèi)存池對比

圖片

內(nèi)存申請對比

圖片

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 服務(wù)器
    +關(guān)注

    關(guān)注

    12

    文章

    9231

    瀏覽量

    85626
  • 內(nèi)存
    +關(guān)注

    關(guān)注

    8

    文章

    3034

    瀏覽量

    74136
  • API
    API
    +關(guān)注

    關(guān)注

    2

    文章

    1504

    瀏覽量

    62162
  • malloc
    +關(guān)注

    關(guān)注

    0

    文章

    52

    瀏覽量

    73
收藏 人收藏

    評論

    相關(guān)推薦

    C++內(nèi)存的設(shè)計與實現(xiàn)

    內(nèi)存化技術(shù)中的一種形式。通常我們在編寫程序的時候回使用 new delete 這些關(guān)鍵字來向操作系統(tǒng)申請內(nèi)存,而這樣造成的后果就是每次申請內(nèi)存
    發(fā)表于 09-23 10:22 ?934次閱讀

    Linux內(nèi)存系統(tǒng):內(nèi)存使用場景

    out of memory 的時代過去了嗎?no,內(nèi)存再充足也不可任性使用。1、內(nèi)存的使用場景· page 管理· slab(kmalloc、內(nèi)存
    發(fā)表于 08-25 07:42

    =>的使用場景有哪些

    使用場景
    發(fā)表于 10-27 13:25

    內(nèi)存可以調(diào)節(jié)內(nèi)存的大小嗎

    嵌入式–內(nèi)存直接上代碼,自己體會。嵌入式設(shè)備,一般keil提供的堆很小,一般都不使用。使用內(nèi)存,自己可以調(diào)節(jié)內(nèi)存大小。頭文件 mallo
    發(fā)表于 12-17 07:00

    內(nèi)存的概念和實現(xiàn)原理概述

    { //一:內(nèi)存的概念和實現(xiàn)原理概述//malloc:內(nèi)存浪費,頻繁分配小塊內(nèi)存,則浪費更加顯得明顯//“內(nèi)存
    發(fā)表于 12-17 06:44

    MS9331的應(yīng)用場景是什么?

    MS9331的應(yīng)用場景是什么?
    發(fā)表于 02-11 06:41

    關(guān)于RT-Thread內(nèi)存管理的內(nèi)存簡析

    這篇文章繼續(xù)介紹 RT-Thread 內(nèi)存管理剩下的部分——內(nèi)存。為何引入內(nèi)存內(nèi)存堆雖然方
    發(fā)表于 04-06 17:02

    RT-Thread內(nèi)存管理之內(nèi)存實現(xiàn)分析

    適合它們的高效率的內(nèi)存分配算法,就將變得復(fù)雜化。RT-Thread 操作系統(tǒng)在內(nèi)存管理上,根據(jù)上層應(yīng)用及系統(tǒng)資源的不同,有針對性地提供了不同的內(nèi)存分配管理算法??傮w上可分為兩類:內(nèi)存
    發(fā)表于 10-17 15:06

    什么是內(nèi)存

    1什么是內(nèi)存 1.1化技術(shù) 所謂“化技術(shù)”,就是程序先向系統(tǒng)申請過量的資源,然后自己管理,以備不時之需。之所以要申請過 量的資源,是因為每次申請該資源都有較大的開銷,不如提前申請
    的頭像 發(fā)表于 11-08 16:26 ?918次閱讀
    什么是<b class='flag-5'>內(nèi)存</b><b class='flag-5'>池</b>

    高并發(fā)內(nèi)存項目實現(xiàn)

    本項目實現(xiàn)了一個高并發(fā)內(nèi)存,參考了Google的開源項目tcmalloc實現(xiàn)的簡易版;其功能就是實現(xiàn)高效的多線程內(nèi)存管理。由功能可知,高并發(fā)指的是高效的多線程,而內(nèi)存
    的頭像 發(fā)表于 11-09 11:16 ?736次閱讀
    高并發(fā)<b class='flag-5'>內(nèi)存</b><b class='flag-5'>池</b>項目實現(xiàn)

    了解連接、線程、內(nèi)存、異步請求

    可被重復(fù)使用像常見的線程、內(nèi)存、連接、對象都具有以上的共同特點。 連接 什么是數(shù)據(jù)庫連
    的頭像 發(fā)表于 11-09 14:44 ?1392次閱讀
    了解連接<b class='flag-5'>池</b>、線程<b class='flag-5'>池</b>、<b class='flag-5'>內(nèi)存</b><b class='flag-5'>池</b>、異步請求<b class='flag-5'>池</b>

    如何實現(xiàn)一個高性能內(nèi)存

    寫在前面 本文的內(nèi)存代碼是改編自Nginx的內(nèi)存源碼,思路幾乎一樣。由于Nginx源碼的變量命名我不喜歡,又沒有注釋,看得我很難受。想自己寫一版容易理解的代碼。 應(yīng)
    的頭像 發(fā)表于 11-10 11:11 ?685次閱讀
    如何實現(xiàn)一個高性能<b class='flag-5'>內(nèi)存</b><b class='flag-5'>池</b>

    nginx內(nèi)存源碼設(shè)計

    造輪子內(nèi)存原因引入 作為C/C++程序員, 相較JAVA程序員的一個重大特征是我們可以直接訪問內(nèi)存, 自己管理內(nèi)存, 這個可以說是我們的特色, 也是我們的苦楚了. java可以有虛擬
    的頭像 發(fā)表于 11-13 11:51 ?701次閱讀
    nginx<b class='flag-5'>內(nèi)存</b><b class='flag-5'>池</b>源碼設(shè)計

    內(nèi)存主要解決的問題

    內(nèi)存的定義 1.化技術(shù) 是在計算機技術(shù)中經(jīng)常使用的一種設(shè)計模式,其內(nèi)涵在于:將程序中需要經(jīng)常使用的核心資源 先申請出來,放到一個池內(nèi),由程序自己管理,這樣可以提高資源的使用效率
    的頭像 發(fā)表于 11-13 15:23 ?730次閱讀
    <b class='flag-5'>內(nèi)存</b><b class='flag-5'>池</b>主要解決的問題

    反射內(nèi)存卡使用場景

    反射內(nèi)存卡相關(guān)應(yīng)用場景?
    發(fā)表于 09-07 16:54 ?0次下載
    主站蜘蛛池模板: 99re8久久热在线视频| 亚洲日韩欧美国产专区| 极品少妇粉嫩小泬啪啪AV| 第九色区av天堂| 99re 这里只有精品| 2017最新伦理伦理片67| 岳打开双腿开始配合日韩视频| 亚洲精品无码一区二区三区四虎| 无人区大片中文字幕在线| 色婷婷狠狠97成为人免费| www免费看.男人的天堂| 97人妻精品全国免费视频| 中文字幕不卡在线视频| 最近的2019中文字幕国语完整版| 伊人久在线| 在线不卡日本v二区| 在线一本码道高清| 最近高清日本免费| 91国在线视频| 99国产在线观看| RUN AWAY无删减全集动漫| FREESEXVIDEO 性老少配| 北条麻妃夫の友人196| 国产成A人片在线观看| 国产精品嫩草99AV在线| 国产午夜精品视频在线播放| 狠狠色丁香婷婷久久综合五月 | 欧美最猛性xxxxx亚洲精品| 人妻洗澡被强公日日澡| 色欲av蜜臀av高清| 迅雷成人下载| 伊人色综合久久大香| 99RE久久精品国产| 俄罗斯14一18处交| 国产亚洲美女在线视频视频| 久久精品一区二区免费看| 蜜桃久久久亚洲精品成人| 日本无码专区亚洲麻豆| 西施打开双腿下面好紧| 一区二区乱子伦在线播放| A级超碰视频在线观看|