【移動(dòng)應(yīng)用開(kāi)發(fā)技術(shù)】SGI版本空間配置器_第1頁(yè)
【移動(dòng)應(yīng)用開(kāi)發(fā)技術(shù)】SGI版本空間配置器_第2頁(yè)
【移動(dòng)應(yīng)用開(kāi)發(fā)技術(shù)】SGI版本空間配置器_第3頁(yè)
【移動(dòng)應(yīng)用開(kāi)發(fā)技術(shù)】SGI版本空間配置器_第4頁(yè)
【移動(dòng)應(yīng)用開(kāi)發(fā)技術(shù)】SGI版本空間配置器_第5頁(yè)
已閱讀5頁(yè),還剩15頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

【移動(dòng)應(yīng)用開(kāi)發(fā)技術(shù)】SGI版本空間配置器

1、STL中的空間配置器

在STL中,空間配置器分了2組,分別為一級(jí)空間配置器和二級(jí)空間配置器,但是它們都有自己各自運(yùn)用的場(chǎng)合;一般說(shuō)來(lái),一級(jí)空間配置器一般分配的空間大于128B,二級(jí)空間配置器的分配空間為小于128B.

其中SGI中的STL的空間配置器設(shè)計(jì)哲學(xué)如下:

(1)、向systemheap要求申請(qǐng)空間

(2)、考慮多線程的狀態(tài)

(3)、考慮內(nèi)存不足時(shí)的應(yīng)變措施

(4)、考慮過(guò)多"小型區(qū)塊"可能造成的內(nèi)存碎片問(wèn)題

在剖析源碼時(shí),為了將問(wèn)題控制在一定的復(fù)雜度內(nèi),以下源碼皆排除多線程狀態(tài)的處理;

0:表示非多線程版本;

inst:表示不關(guān)注多線程的問(wèn)題;2、一級(jí)空間配置器

(1)、為內(nèi)存不足做好準(zhǔn)備:(1)、拋出異常,也就是輸出一句話;(2)、調(diào)用自己設(shè)置的函數(shù)去處理(比如說(shuō)是釋放一些空間,回收一些碎片的空間);

一級(jí)空間配置器的本質(zhì):模仿實(shí)現(xiàn)了set_new_handler機(jī)制;

set_new_handler機(jī)制的實(shí)現(xiàn):(1)、定義一個(gè)函數(shù)指針;(2)、定義一個(gè)函數(shù);(3)、賦值比較;

(2)、抽取的代碼實(shí)現(xiàn)#if

1

#include<iostream>

#include<new>

#include<malloc.h>

using

namespace

std;

//#define

__THROW_BAD_ALLOC

throw

bad_alloc

#define

__THROW_BAD_ALLOC

cerr<<"Throw

bad

alloc,

Out

Of

Memory."<<endl;

exit(1)

//定義異常,就是輸出一句話,并且結(jié)束程序.

#elif

!defined

(__THROW_BAD_ALLOC)

//如果沒(méi)有定義這個(gè)異常,下面就定義

#include<iostream.h>

#define

__THROW_BAD_ALLOC

cerr<<"out

of

memory"<<endl;

exit(1);

#endif

template<int

inst>

class

__malloc_alloc_template{

private:

static

void*

oom_malloc(size_t);

//對(duì)申請(qǐng)空間失敗的處理函數(shù)

static

void*

oom_realloc(void

*,

size_t);

//對(duì)擴(kuò)展空間失敗處理的函數(shù)

static

void(*

__malloc_alloc_oom_handler)();

//定義一個(gè)函數(shù)指針

public:

static

void*

allocate(size_t

n){

//分配空間

void

*result

=

malloc(n);

if(0

==

result)

result

=

oom_malloc(n);

//分配空間失敗,調(diào)用oom_malloc()函數(shù)

return

result;

//將申請(qǐng)的空間的地址返回

}

static

void

deallocate(void

*p,

size_t){

free(p);

//釋放空間

}

static

void*

reallocate(void

*p,

size_t,

size_t

new_sz){

void

*result

=

realloc(p,

new_sz);

//擴(kuò)展新空間;

if(0

==

result)

//擴(kuò)展失敗

oom_realloc(p,new_sz);

//調(diào)用擴(kuò)展空間失敗的處理函數(shù)

return

result;

}

public:

//set_new_handler(Out_Of_Memory);

static

void(*set_malloc_handler(void(*f)()))(){

//這是一個(gè)指針函數(shù),函數(shù)名稱:set_malloc_handler,參數(shù):是一個(gè)函數(shù)指針,返回值:是一個(gè)函數(shù)指針;

void(*old)()

=

__malloc_alloc_oom_handler;

//將原有空間的地址保存在old中;

__malloc_alloc_oom_handler

=

f;

//將自己定義的函數(shù)地址給__malloc_alloc_oom_handler;

return

old;

//每次可以保存其上一次的地址.

}

};

template<int

inst>

void

(*__malloc_alloc_template<inst>::__malloc_alloc_oom_handler)()

=

0;

//對(duì)定義的靜態(tài)函數(shù)指針初始化為0;

template<int

inst>

void*

__malloc_alloc_template<inst>::oom_malloc(size_t

n){

//處理空間失敗的問(wèn)題

void

*result;

void(*

my_malloc_handler)();

//定義一個(gè)函數(shù)指針;

for(;;){

my_malloc_handler

=

__malloc_alloc_oom_handler;

if(0

==

my_malloc_handler){

//自己沒(méi)有定義處理空間失敗的新函數(shù)

__THROW_BAD_ALLOC;

//異常拋出;程序終止;

}

(*my_malloc_handler)();

//調(diào)用自己編寫的處理函數(shù)(一般都是回收空間之類的);

result

=

malloc(n);

//在此申請(qǐng)分配空間

if(result){

//申請(qǐng)成功

return

result;

//將地址返回;

}//那么,這個(gè)程序?qū)?huì)一直持續(xù)到空間分配成功才最終返回.

}

}

template<int

inst>

void*

__malloc_alloc_template<inst>::oom_realloc(void

*p,

size_t

n){

void(*my_malloc_handler)();

//函數(shù)指針

void

*result;

for(;;){

my_malloc_handler

=

__malloc_alloc_oom_handler;

//將這個(gè)給其賦值

if(0

==

my_malloc_handler){

//外面沒(méi)有定義處理的函數(shù)

__THROW_BAD_ALLOC;

//異常拋出,程序結(jié)束.

}

(*my_malloc_handler)();

//調(diào)用自己編寫的處理函數(shù)(一般都是回收空間之類的);

result

=

realloc(p,

n);

//再次擴(kuò)展空間分配;

if(result){

//擴(kuò)展成功,就返回

return

result;

}

//一直持續(xù)成功,知道擴(kuò)展空間分配成功才返回;

}

}

typedef

__malloc_alloc_template<0>

malloc_alloc;

//一級(jí)空間配置器:malloc_alloc;第一級(jí)空間配置器就是:(1)、對(duì)malloc、free的簡(jiǎn)單封裝;(2)、模擬C++的set_new_handler()已處理內(nèi)存不足的情況;總結(jié):

(1)、一級(jí)空間配置器其實(shí)就是先自己開(kāi)辟空間,要是失敗了;

(2)、調(diào)用處理空間失敗的函數(shù),在其內(nèi)部,先看我們自己在外面有沒(méi)有寫針對(duì)這個(gè)的處理函數(shù),要是沒(méi)寫,就是異常拋出,程序結(jié)束;

(3)、要是寫了,就調(diào)用我們自己寫的函數(shù),在次分配空間,進(jìn)入死循環(huán)中,直到空間分配成功,方可退出循環(huán);

還要注意的是:staticvoid(*set_malloc_handler(void(*f)()))();這是一個(gè)指針函數(shù);3、二級(jí)空間配置器

(1)、當(dāng)所分配的空間小于128B時(shí),則以內(nèi)存池去管理;對(duì)小額區(qū)塊,自動(dòng)將內(nèi)存調(diào)至8的倍數(shù),并維護(hù)16個(gè)自由鏈表,各自管理大小分別為:8162432404856128B的小額區(qū)塊;

(2)、剛開(kāi)始所分配的內(nèi)存空間,一半當(dāng)做自由鏈表,一半當(dāng)做內(nèi)存池;當(dāng)再次分配同樣大小的空間時(shí),直接先從自由鏈表中分配;當(dāng)再次分配其他大小空間時(shí),先看內(nèi)存池中有無(wú)空間,有的話,直接分配,掛載即可。模型如下:整個(gè)分配空間都是很節(jié)省化的:其抽取代碼如下://二級(jí)空間配置器由自由鏈表和內(nèi)存池組成;

enum

{__ALIGN

=

8};

//一塊鏈表8B

enum

{__MAX_BYTES

=

128};

//小于128B調(diào)用二級(jí)的

enum

{__NFREELISTS

=

__MAX_BYTES

/

__ALIGN};

//一共分配16個(gè)自由鏈表,負(fù)責(zé)16種次分配能力.

template<bool

threads,

int

inst>

//不考慮多線程狀態(tài);

class

__default_alloc_template{

public:

static

void*

allocate(size_t

n);

//分配空間

static

void

deallocate(void

*p,

size_t

n);

//銷毀空間

static

void*

reallocate(void

*p,

size_t,

size_t

new_sz);

//擴(kuò)展空間

private:

static

size_t

ROUND_UP(size_t

bytes){

//向上調(diào)整函數(shù);

return

(((bytes)

+

__ALIGN-1)

&

~(__ALIGN-1));

//調(diào)為當(dāng)前字節(jié)是8的整數(shù)倍.

}

private:

union

obj{

//共用體

union

obj

*

free_list_link;

//自由鏈表的指向

char

client_data[1];

};

private:

static

obj*

volatile

free_list[__NFREELISTS];

//定義了一個(gè)指針數(shù)組;

static

size_t

FREELIST_INDEX(size_t

bytes){

//求當(dāng)前字節(jié)的自由鏈表的下標(biāo);

return

((bytes)+__ALIGN-1)

/

__ALIGN-1;

}

private:

static

char

*start_free;

//開(kāi)始空間的下標(biāo)

static

char

*end_free;

//結(jié)束空間的下標(biāo)

static

size_t

heap_size;

//堆空間大小

static

void

*refill(size_t

n);

//填充函數(shù)

static

char*

chunk_alloc(size_t

size,

int

&nobjs);

//

};

template<bool

threads,

int

inst>

//以下都是對(duì)靜態(tài)變量的初始化,都為0;

char*

__default_alloc_template<threads,

inst>::start_free

=

0;

template<bool

threads,

int

inst>

char*

__default_alloc_template<threads,

inst>::end_free

=

0;

template<bool

threads,

int

inst>

size_t

__default_alloc_template<threads,

inst>::heap_size

=

0;

template<bool

threads,

int

inst>

typename

__default_alloc_template<threads,

inst>::obj*

volatile

__default_alloc_template<threads,

inst>::free_list[__NFREELISTS]

=

{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

template<bool

threads,

int

inst>

void*

__default_alloc_template<threads,

inst>::allocate(size_t

n){

//分配空間的函數(shù)

obj

*

volatile

*my_free_list;

obj

*result;

if(n

>

__MAX_BYTES){

//分配空間的大小大于128B的話,就調(diào)用一級(jí)空間配置器

return

malloc_alloc::allocate(n);

}

my_free_list

=

free_list

+

FREELIST_INDEX(n);

//free_list是二維數(shù)組名稱,找往哪個(gè)鏈下掛;

result

=

*my_free_list;

//取出其值,因?yàn)閙y_free_list是二階指針;

if(result

==

0){

//沒(méi)有內(nèi)存池空間;

void

*r

=

refill(ROUND_UP(n));

//調(diào)用refill()函數(shù)

return

r;

}

*my_free_list

=

result->free_list_link;

//進(jìn)行掛載連接;

return

result;

}

template<bool

threads,

int

inst>

void*

__default_alloc_template<threads,

inst>::refill(size_t

n){

//沒(méi)有可用區(qū)塊時(shí),就調(diào)用refill()函數(shù);

int

nobjs

=

20;//就是要分20塊;

char

*chunk

=

chunk_alloc(n,

nobjs);

//調(diào)用內(nèi)存池函數(shù);

obj

*

volatile

*my_free_list;

obj

*result;

obj

*current_obj,

*next_obj;

int

i;

if(1

==

nobjs){

//當(dāng)分配到只有一塊空間時(shí),直接返回.

return

chunk;

}

my_free_list

=

free_list

+

FREELIST_INDEX(n);

//找到對(duì)應(yīng)的下標(biāo),進(jìn)行連接的工作;

result

=

(obj*)chunk;

*my_free_list

=

next_obj

=

(obj*)(chunk+n);

for(i=1;

;

++i){

current_obj

=

next_obj;

next_obj

=

(obj*)((char*)next_obj+n);

if(nobjs

-

1

==

i){

//進(jìn)行連接工作;

current_obj->free_list_link

=

0;

break;

}else{

current_obj->free_list_link

=

next_obj;

}

}

return

result;

}

template<bool

threads,

int

inst>

char*

__default_alloc_template<threads,

inst>::chunk_alloc(size_t

size,

int

&nobjs){

//內(nèi)存池函數(shù)

char

*result;

//關(guān)鍵要明白以下的各種情況;

size_t

total_bytes

=

size

*

nobjs;

//這里的size已經(jīng)是上調(diào)過(guò)的字節(jié);求取20*size個(gè)字節(jié)的大小

size_t

bytes_left

=

end_free

-

start_free;

//剛開(kāi)始,遺留字節(jié)為0;

if(bytes_left

>=

total_bytes){

//不成立

result

=

start_free;

start_free

+=

total_bytes;

return

result;

}else

if(bytes_left

>=

size){

//不成立

nobjs

=

bytes_left

/

size;

total_bytes

=

size

*

nobjs;

result

=

start_free;

start_free

+=

total_bytes;

return

result;

}else{

//走的就是下面的這條路線

size_t

bytes_to_get

=

2

*

total_bytes

+

ROUND_UP(heap_size

>>

4);

//申請(qǐng)2倍的total_bytes;

if(bytes_left

>

0){

//遺留字節(jié)數(shù)=0,所以這條語(yǔ)句不成立;

obj

*

volatile

*

my_free_list

=

free_list

+

FREELIST_INDEX(bytes_left);

((obj*)start_free)->free_list_link

=

*my_free_list;

*my_free_list

=

(obj

*)start_free;

}

start_free

=

(char

*)malloc(bytes_to_get);

//申請(qǐng)空間;

if(0

==

start_free){

int

i;

obj

*

volatile

*my_free_list,

*p;

for(i=size;

i<=__MAX_BYTES;

i

+=

__ALIGN){

my_free_list

=

free_list

+

FREELIST_INDEX(i);

p

=

*my_free_list;

if(0

!=

p){

*my_free_list

=

p->free_list_link;

start_free

=

(char

*)p;

end_free

=

start_free

+

i;

return

chunk_alloc(size,

nobjs);

}

}

end_free

=

0;

start_free

=

(char

*)malloc_alloc::allocate(bytes_to_get);

}

heap_size

+=

bytes_to_get;

//記錄此時(shí)堆空間的大小;

end_free

=

start_free

+

bytes_to_get;

//指向了最后;

return

chunk_alloc(size,

nobjs);

//上去在此調(diào)用這個(gè)函數(shù);

}

}nobjs=20;這個(gè)是經(jīng)驗(yàn)值,開(kāi)辟空間留有余地,方便直接查找,以后就不用再次開(kāi)辟空間了,提高了效率;這個(gè)我們自己給不同的字節(jié)情況(小于128B的),就會(huì)知道其中發(fā)生了什么;SGI第二級(jí)空間配置器:

(1)、維護(hù)16個(gè)自由鏈表,分別有16種小型區(qū)塊的配置能力;如果內(nèi)存不足,調(diào)用一級(jí)空間配置器(那里有處理程序);

(2)、如果申請(qǐng)空間的需求大于128B,就調(diào)用一級(jí)空間配置器.總結(jié):

(1)、二級(jí)空間配置器(最后山窮水盡)>調(diào)用一級(jí)空間配置器>(1)、拋出異常(2)、調(diào)用自己編寫的處理函數(shù);

STL內(nèi)存配置思想:C++STL是兩級(jí)配置內(nèi)存的,具體來(lái)說(shuō):第一級(jí)負(fù)責(zé)管理大塊內(nèi)存,要保證有類似new-handler的機(jī)制;第二級(jí)負(fù)責(zé)管理小塊內(nèi)存,為了更好的管理內(nèi)存碎片,建立16個(gè)鏈表,每個(gè)鏈表“穿”著一塊一塊固定大小的內(nèi)存,這16個(gè)鏈表(0至15)分別“穿”的內(nèi)存是8、16、24…128倍數(shù)關(guān)系。需要內(nèi)存時(shí),從“合適”的鏈表取走(因?yàn)檫@里情況比較多,不能一一說(shuō)道了),如果“合適”的鏈表內(nèi)存不夠用了,從內(nèi)存池里拿,如果內(nèi)存池不夠用了,從運(yùn)行時(shí)heap里拿,如果heap也溢出了,就交給第一級(jí)配置器,因?yàn)樗衧et_new-handler機(jī)制。所以,當(dāng)堆上的東西用完之后,的趕緊還回來(lái)。4、完整代碼、測(cè)試代碼、測(cè)試結(jié)果

(1)、抽取出來(lái)的完整代碼#if

1

#include<iostream>

#include<new>

#include<malloc.h>

using

namespace

std;

//#define

__THROW_BAD_ALLOC

throw

bad_alloc

#define

__THROW_BAD_ALLOC

cerr<<"Throw

bad

alloc,

Out

Of

Memory."<<endl;

exit(1)

//定義異常,就是輸出一句話,并且結(jié)束程序.

#elif

!defined

(__THROW_BAD_ALLOC)

//如果沒(méi)有定義這個(gè)異常,下面就定義

#include<iostream.h>

#define

__THROW_BAD_ALLOC

cerr<<"out

of

memory"<<endl;

exit(1);

#endif

template<int

inst>

class

__malloc_alloc_template{

private:

static

void*

oom_malloc(size_t);

//對(duì)申請(qǐng)空間失敗的處理函數(shù)

static

void*

oom_realloc(void

*,

size_t);

//對(duì)擴(kuò)展空間失敗處理的函數(shù)

static

void(*

__malloc_alloc_oom_handler)();

//定義一個(gè)函數(shù)指針

public:

static

void*

allocate(size_t

n){

//分配空間

void

*result

=

malloc(n);

if(0

==

result)

result

=

oom_malloc(n);

//分配空間失敗,調(diào)用oom_malloc()函數(shù)

return

result;

//將申請(qǐng)的空間的地址返回

}

static

void

deallocate(void

*p,

size_t){

free(p);

//釋放空間

}

static

void*

reallocate(void

*p,

size_t,

size_t

new_sz){

void

*result

=

realloc(p,

new_sz);

//擴(kuò)展新空間;

if(0

==

result)

//擴(kuò)展失敗

oom_realloc(p,new_sz);

//調(diào)用擴(kuò)展空間失敗的處理函數(shù)

return

result;

}

public:

//set_new_handler(Out_Of_Memory);

static

void(*set_malloc_handler(void(*f)()))(){

//這是一個(gè)指針函數(shù),函數(shù)名稱:set_malloc_handler,參數(shù):是一個(gè)函數(shù)指針,返回值:是一個(gè)函數(shù)指針;

void(*old)()

=

__malloc_alloc_oom_handler;

//將原有空間的地址保存在old中;

__malloc_alloc_oom_handler

=

f;

//將自己定義的函數(shù)地址給__malloc_alloc_oom_handler;

return

old;

//每次可以保存其上一次的地址.

}

};

template<int

inst>

void

(*__malloc_alloc_template<inst>::__malloc_alloc_oom_handler)()

=

0;

//對(duì)定義的靜態(tài)函數(shù)指針初始化為0;

template<int

inst>

void*

__malloc_alloc_template<inst>::oom_malloc(size_t

n){

//處理空間失敗的問(wèn)題

void

*result;

void(*

my_malloc_handler)();

//定義一個(gè)函數(shù)指針;

for(;;){

my_malloc_handler

=

__malloc_alloc_oom_handler;

if(0

==

my_malloc_handler){

//自己沒(méi)有定義處理空間失敗的新函數(shù)

__THROW_BAD_ALLOC;

//異常拋出;程序終止;

}

(*my_malloc_handler)();

//調(diào)用自己編寫的處理函數(shù)(一般都是回收空間之類的);

result

=

malloc(n);

//在此申請(qǐng)分配空間

if(result){

//申請(qǐng)成功

return

result;

//將地址返回;

}//那么,這個(gè)程序?qū)?huì)一直持續(xù)到空間分配成功才最終返回.

}

}

template<int

inst>

void*

__malloc_alloc_template<inst>::oom_realloc(void

*p,

size_t

n){

void(*my_malloc_handler)();

//函數(shù)指針

void

*result;

for(;;){

my_malloc_handler

=

__malloc_alloc_oom_handler;

//將這個(gè)給其賦值

if(0

==

my_malloc_handler){

//外面沒(méi)有定義處理的函數(shù)

__THROW_BAD_ALLOC;

//異常拋出,程序結(jié)束.

}

(*my_malloc_handler)();

//調(diào)用自己編寫的處理函數(shù)(一般都是回收空間之類的);

result

=

realloc(p,

n);

//再次擴(kuò)展空間分配;

if(result){

//擴(kuò)展成功,就返回

return

result;

}

//一直持續(xù)成功,知道擴(kuò)展空間分配成功才返回;

}

}

typedef

__malloc_alloc_template<0>

malloc_alloc;

//一級(jí)空間配置器:malloc_alloc;

/////////////////////////////////////////////////////////////////////////////////////

//二級(jí)空間配置器由自由鏈表和內(nèi)存池組成;

enum

{__ALIGN

=

8};

//一塊鏈表8B

enum

{__MAX_BYTES

=

128};

//小于128B調(diào)用二級(jí)的

enum

{__NFREELISTS

=

__MAX_BYTES

/

__ALIGN};

//一共分配16個(gè)自由鏈表,負(fù)責(zé)16種次分配能力.

template<bool

threads,

int

inst>

//不考慮多線程狀態(tài);

class

__default_alloc_template{

public:

static

void*

allocate(size_t

n);

//分配空間

static

void

deallocate(void

*p,

size_t

n);

//銷毀空間

static

void*

reallocate(void

*p,

size_t,

size_t

new_sz);

//擴(kuò)展空間

private:

static

size_t

ROUND_UP(size_t

bytes){

//向上調(diào)整函數(shù);

return

(((bytes)

+

__ALIGN-1)

&

~(__ALIGN-1));

//調(diào)為當(dāng)前字節(jié)是8的整數(shù)倍.

}

private:

union

obj{

//共用體

union

obj

*

free_list_link;

//自由鏈表的指向

char

client_data[1];

};

private:

static

obj*

volatile

free_list[__NFREELISTS];

//定義了一個(gè)指針數(shù)組;

static

size_t

FREELIST_INDEX(size_t

bytes){

//求當(dāng)前字節(jié)的自由鏈表的下標(biāo);

return

((bytes)+__ALIGN-1)

/

__ALIGN-1;

}

private:

static

char

*start_free;

//開(kāi)始空間的下標(biāo)

static

char

*end_free;

//結(jié)束空間的下標(biāo)

static

size_t

heap_size;

//堆空間大小

static

void

*refill(size_t

n);

//填充函數(shù)

static

char*

chunk_alloc(size_t

size,

int

&nobjs);

//

};

template<bool

threads,

int

inst>

//以下都是對(duì)靜態(tài)變量的初始化,都為0;

char*

__default_alloc_template<threads,

inst>::start_free

=

0;

template<bool

threads,

int

inst>

char*

__default_alloc_template<threads,

inst>::end_free

=

0;

template<bool

threads,

int

inst>

size_t

__default_alloc_template<threads,

inst>::heap_size

=

0;

template<bool

threads,

int

inst>

typename

__default_alloc_template<threads,

inst>::obj*

volatile

__default_alloc_template<threads,

inst>::free_list[__NFREELISTS]

=

{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

template<bool

threads,

int

inst>

void*

__default_alloc_template<threads,

inst>::allocate(size_t

n){

//分配空間的函數(shù)

obj

*

volatile

*my_free_list;

obj

*result;

if(n

>

__MAX_BYTES){

//分配空間的大小大于128B的話,就調(diào)用一級(jí)空間配置器

return

malloc_alloc::allocate(n);

}

my_free_list

=

free_list

+

FREELIST_INDEX(n);

//free_list是二維數(shù)組名稱,找往哪個(gè)鏈下掛;

result

=

*my_free_list;

//取出其值,因?yàn)閙y_free_list是二階指針;

if(result

==

0){

//沒(méi)有內(nèi)存池空間;

void

*r

=

refill(ROUND_UP(n));

//調(diào)用refill()函數(shù)

return

r;

}

*my_free_list

=

result->free_list_link;

//進(jìn)行掛載連接;

return

result;

}

template<bool

threads,

int

inst>

void*

__default_alloc_template<threads,

inst>::refill(size_t

n){

//沒(méi)有可用區(qū)塊時(shí),就調(diào)用refill()函數(shù);

int

nobjs

=

20;//就是要分20塊;

char

*chunk

=

chunk_alloc(n,

nobjs);

//調(diào)用內(nèi)存池函數(shù);

obj

*

volatile

*my_free_list;

obj

*result;

obj

*current_obj,

*next_obj;

int

i;

if(1

==

nobjs){

//當(dāng)分配到只有一塊空間時(shí),直接返回.

return

chunk;

}

my_free_list

=

free_list

+

FREELIST_INDEX(n);

//找到對(duì)應(yīng)的下標(biāo),進(jìn)行連接的工作;

result

=

(obj*)chunk;

*my_free_list

=

next_obj

=

(obj*)(chunk+n);

for(i=1;

;

++i){

current_obj

=

next_obj;

next_obj

=

(obj*)((char*)next_obj+n);

if(nobjs

-

1

==

i){

//進(jìn)行連接工作;

current_obj->free_list_link

=

0;

break;

}else{

current_obj->free_list_link

=

next_obj;

}

}

return

result;

}

template<bool

threads,

int

inst>

char*

__default_alloc_template<threads,

inst>::chunk_alloc(size_t

size,

int

&nobjs){

//內(nèi)存池函數(shù)

char

*result;

//關(guān)鍵要明白以下的各種情況;

size_t

total_bytes

=

size

*

nobjs;

//這里的size已經(jīng)是上調(diào)過(guò)的字節(jié);求取20*size個(gè)字節(jié)的大小

size_t

bytes_left

=

end_free

-

start_free;

//剛開(kāi)始,遺留字節(jié)為0;

if(bytes_left

>=

total_bytes){

//不成立

result

=

start_free;

start_free

+=

total_bytes;

return

result;

}else

if(bytes_left

>=

size){

//不成立

nobjs

=

bytes_left

/

size;

total_bytes

=

size

*

nobjs;

result

=

start_free;

start_free

+=

total_bytes;

return

result;

}else{

//走的就是下面的這條路線

size_t

bytes_to_get

=

2

*

total_bytes

+

ROUND_UP(heap_size

>>

4);

//申請(qǐng)2倍的total_bytes;

if(bytes_left

>

0){

//遺留字節(jié)數(shù)=0,所以這條語(yǔ)句不成立;

obj

*

volatile

*

my_free_list

=

free_list

+

FREELIST_INDEX(bytes_left);

((obj*)start_free)->free_list_link

=

*my_free_list;

*my_free_list

=

(obj

*)start_free;

}

start_free

=

(char

*)malloc(bytes_to_get);

//申請(qǐng)空間;

if(0

==

start_free){

int

i;

obj

*

volatile

*my_free_list,

*p;

for(i=size;

i<=__MAX_BYTES;

i

+=

__ALIGN){

my_free_list

=

free_list

+

FREELIST_INDEX(i);

p

=

*my_free_list;

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論