程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 零零散散學算法之淺析內存管理的方式

零零散散學算法之淺析內存管理的方式

編輯:C++入門知識

解析內存管理的方式   正文          說到內存分配,我們立刻就會想到malloc()、calloc()等申請內存的接口,說到內存分配的算法,我們會想到Buddy和Slab等分配算法。那麼你有沒有思考過,申請的內存是如何管理的呢?管理的方式都有哪些?這就是本文將要討論的。          本文將介紹兩種內存管理的方法:鏈表法和比特位法。   第零節 問題初始化          假設現有一坨大小為M的內存,我們將它分為N塊,那麼每塊的大小就是BLOCK_SIZE = M/N,如下圖所示:   第一節 鏈表法          所謂鏈表法內存管理,就是說將已經分好的一坨內存分成了許多的小塊,然後將每個小塊以鏈表的形式串起來。如下圖:          從圖中可看到,我們在每個小塊中添加了名為link的鏈表節點,它表示為: [cpp]   struct list_head   {       struct list_head *next, *prev;   };   附注:在內核中該鏈表為雙向鏈表,不過在上圖中為了簡潔,我將其表示為單鏈表。          於是,我們就可以用一個名為head的頭結點將這些小塊串聯起來了。當我們使用時,只需從鏈表上摘一個即可,用完之後就可還回。利用鏈表來管理內存的優點有以下兩點:          1. 即用即拿,用完即還(方便快捷):就是說當我們需要在這坨申請好的內存中使用一個或者幾個小塊時,我們就可根據需要,從鏈表上摘下來一個或者幾個,用完之後直接還回鏈表中即可。          2. 管理流與數據流的融合與分離(節省空間):當我們利用鏈表法管理內存時,我們只需知道每個塊的link,這樣我們就能利用link來管理每個塊,我們說它們是融合的;當你要使用某個塊時,將其從鏈表中摘下來,這個時候我們就用這個塊來進行數據流操作,對於link我們並不關心,在這個角度上我們說它們是分離的。不論融合與分離,我們在操作時並沒有用到額外的空間,而是在每個塊的內部解決了管理流與數據流。          好了,這就是鏈表法內存管理。節末,我還是給出鏈表法的代碼: [cpp]   /**   *  鏈表法內存管理:內存初始化     *  addr: 表示塊的起始地址   *  block_size: 表示每個塊的大小   *  block_number: 表示塊的個數   */   void MemoryInit(void* addr, unsigned long block_size, unsigned int block_number)   {       int i = 0;       struct list_head *link = (struct list_head*)addr;          for(; i < block_number; i++)       {           list_add_tail(link, head);//添加到鏈表尾部           addr += block_size;           link = (struct list_head*)addr;       }   }   [cpp]   /**   *  鏈表法內存管理:內存塊分配   */   void* alloc_blkmem(void)   {       struct list_head *link = NULL;       if(!list_empty(head))//鏈表不為空       {           link = head->next;           list_del_init(link);//從鏈表中摘除       }       return link;   }   [cpp]   /**   *  鏈表法內存管理:內存塊釋放   *   *  addr: 表示塊的起始地址   */   void free_blkmem(void* addr)   {       struct list_head *link = (struct list_head*)addr;       list_add_tail(link, head);//還回到鏈表中   }   第二節 比特位法          和鏈表法相比,比特位法就更簡單了。比特位的思想很簡單,就是說當某個塊沒有被使用時,我們讓該塊對應位置的bit位為0,當這個塊被使用時,就將它的bit位置為1。如下圖:
         比特位法的確很直觀,這是它的優點,但是和鏈表法相比,它在時間和空間上都不及鏈表法。我們來看看:          在時間上:鏈表法是即用即拿,而比特位法則不然,它必須對bit表進行遍歷,當bit位為0時方可取用;          在空間上:鏈表法不需額外的空間,而比特位法則取額外的空間來存儲bitmap表,有一個塊就得對應一個bit位,當數據塊很多時,這也是一筆不消的開銷。          雖然比特位法在時間上和空間上都不是很理想,但是它很直觀,易理解。它也很常用!          好了,比特位法就是個這,因為它很直觀,所以我用很簡單的幾句話就說完了。節末,還是老辦法,給出比特位法的代碼,縱然它很簡單! [cpp]  /** 設置bitmap的指定位   *   *  src: 表示bitmap   *  index:表示指定位   */   void bitmap_set_bit(void *src, unsigned int index)   {       unsigned short*    data_bitmap = (unsigned short *)src;       data_bitmap[index] |= 1 << index;   }   www.2cto.com [cpp]   /** 清除bitmap的指定位   *   *  src: 表示bitmap   *  index:表示指定位   */   void bitmap_clear_bit(void *src, unsigned int index)   {       unsigned short*    data_bitmap = (unsigned short *)src;       data_bitmap[index]  &=  ~(1 << index);   }   第三節 結束語          想想、寫寫、畫畫......  

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved