歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> C語言內存池使用模型

C語言內存池使用模型

日期:2017/3/1 10:09:09   编辑:Linux編程

在用C語言開發時,特別是在服務器端,內存的使用會成為系統性能的一個瓶頸,如頻繁的分配和釋放內存,會不斷的增加系統的內存碎片,影響內核之後分配內存的效率,這個時候一個比較可行的做法是采用內存池,先分配好比較多的內存,然後在這個已經分配的內存裡使用內存,這樣就不需要內核過多的參與內存分配和釋放的過程。

內存池根據應用不同有多種實現的策略,如有些分配很大的內存,然後將內存分配成大小相等的塊,並將每個塊鏈接起來進行管理。

下面對模型介紹的時候,為了簡單,不加入用於調試的編寫技巧和為之准備的結構,其實主要是省去間接調用,有時為了調試,會將文件及所在行以及主要的變量狀態輸出。

一,內存池訪問接口

創建大小為size的新的內存池。

  1. pool_t _pool_new_heap(int size);
從指定內存池中分配大小為size的內存空間, 這些空間會在內存池釋放時,被自動的釋放。
  1. void *pool_malloc(pool_t, int size);
內存池的大小,返回內存池中所有內存塊的大小總和
  1. int pool_size(pool_t p);
釋放內存池,這會導致所有內存被釋放,同時內存池本身也被釋放
  1. void pool_free(pool_t p);
還有其它的一些接口,但這些是主要的接口。

二,數據結構

  1. struct pheap
  2. {
  3. void *block;
  4. int size, used;
  5. };
該結構表示內存池中一個內存塊的抽象表示,

  1. block 用於指向由malloc所分配的內存地址。
  2. size 表示block所指向地址的內存大小。
  3. used 表示多少處於已經使用的狀態。在分配內存時,這個域很重要,它表示內存塊可以被分配的偏移值,也就是從used開始的內存都是可以被從內存池中分配出去的。
  1. struct pfree
  2. {
  3. pool_cleanup_t f;
  4. void *arg;
  5. struct pheap *heap;
  6. struct pfree *next;
  7. };
  8. typedef void (*pool_cleanup_t)(void *arg);
這個結構用於實現一個鏈表,將所有的內存塊鏈接起來。每一個內存塊,對映一個這個結構,也就是每個struct pheap結構,都有一個struct pfree結構將其封裝起來,這個結構主要實現下面幾個功能:

  1. 實現內存塊的鏈表,用struct pfree *next連接起來,這是一個單鏈表。
  2. 內存塊釋放的回調。注冊在釋放內存時,如果釋放這個內存塊,主要是通過pool_cleanup_t f和void *arg兩個域來完成這個功能。
  3. pheap域用於指向需要被放入鏈表的內存塊,就是前面的結構。
  1. typedef struct pool_struct
  2. {
  3. int size;
  4. struct pfree *cleanup;
  5. struct pfree *cleanup_tail;
  6. struct pheap *heap;
  7. } _pool, *pool_t;

結構中的域代表如下:

heap:指向內存池中最新申請的內存塊,在每次申請內存塊時,都會將其指向新的內存塊。

cleanup和cleanup_tail:指向鏈表的頭和尾的指針。

size:表示內存池中內存的大小,包括所有的內存塊。

這個結構的主要功能如下:

  1. 管理內存塊。通過cleanup和clean_tail兩個指針,因為內存塊在內存池中是以單鏈表的形式組織的,這兩個指針分別指向鏈表的頭和尾指針。
  2. 內存池中可用的內存大小。通過size域來統計完成。
  3. 獲取最新的內存塊指針。通過heap指針在每次分配內存塊時重新賦值來實現。
這個內存池的實現,主要是依靠上面三個數據結構來完成,其實估計已經知道的差不多了。下面再討論一些基本的
Copyright © Linux教程網 All Rights Reserved