版權(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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 海水-固體廢棄物低碳膠凝材料開(kāi)發(fā)與機(jī)理研究
- 成都到江西中考數(shù)學(xué)試卷
- “團(tuán)隊(duì)式學(xué)練賽”教學(xué)對(duì)農(nóng)村留守兒童心理健康與鍛煉態(tài)度影響的實(shí)驗(yàn)研究
- 四年級(jí)數(shù)學(xué)(小數(shù)加減運(yùn)算)計(jì)算題專項(xiàng)練習(xí)與答案匯編
- 四年級(jí)數(shù)學(xué)(除數(shù)是兩位數(shù))計(jì)算題專項(xiàng)練習(xí)及答案
- 基于視覺(jué)敘事理論的藝術(shù)博物館展示設(shè)計(jì)研究
- 滄州一模數(shù)學(xué)試卷
- 個(gè)人賣房協(xié)議合同書2篇
- 2025版實(shí)習(xí)就業(yè)保障協(xié)議書范本(專業(yè)版)3篇
- 2025版打印機(jī)網(wǎng)絡(luò)連接與故障排除合同3篇
- 2024多級(jí)AO工藝污水處理技術(shù)規(guī)程
- 2024年江蘇省鹽城市中考數(shù)學(xué)試卷真題(含答案)
- DZ∕T 0287-2015 礦山地質(zhì)環(huán)境監(jiān)測(cè)技術(shù)規(guī)程(正式版)
- 2024年合肥市廬陽(yáng)區(qū)中考二模英語(yǔ)試題含答案
- 質(zhì)檢中心制度匯編討論版樣本
- 藥娘激素方案
- 提高靜脈留置使用率品管圈課件
- GB/T 10739-2023紙、紙板和紙漿試樣處理和試驗(yàn)的標(biāo)準(zhǔn)大氣條件
- 《心態(tài)與思維模式》課件
- C語(yǔ)言程序設(shè)計(jì)(慕課版 第2版)PPT完整全套教學(xué)課件
- 危險(xiǎn)化學(xué)品企業(yè)安全生產(chǎn)標(biāo)準(zhǔn)化課件
評(píng)論
0/150
提交評(píng)論