這幾天看了些關(guān)于內(nèi)存布局的文章,發(fā)帖總結(jié)摘錄下重點(diǎn)。
C語(yǔ)言的內(nèi)存模型
程序代碼區(qū)(code area)
存放函數(shù)體的二進(jìn)制代碼
靜態(tài)數(shù)據(jù)區(qū)(data area)
也稱全局?jǐn)?shù)據(jù)區(qū),包含的數(shù)據(jù)類型比較多乱灵,如全局變量纹份、靜態(tài)變量、一般常量状共、字符串常量。其中:
- 全局變量和靜態(tài)變量的存儲(chǔ)是放在一塊的谁帕,初始化的全局變量和靜態(tài)變量在一塊區(qū)域峡继, 未初始化的全局變量和未初始化的靜態(tài)變量在相鄰的另一塊區(qū)域。
- 常量數(shù)據(jù)(一般常量匈挖、字符串常量)存放在另一個(gè)區(qū)域碾牌。
注意:靜態(tài)數(shù)據(jù)區(qū)的內(nèi)存在程序結(jié)束后由操作系統(tǒng)釋放颠猴。
堆區(qū)(heap area)
一般由程序員分配和釋放,若程序員不釋放小染,程序運(yùn)行結(jié)束時(shí)由操作系統(tǒng)回收翘瓮。malloc()、calloc()裤翩、free()等函數(shù)操作的就是這塊內(nèi)存资盅。
注意:這里所說(shuō)的堆區(qū)與數(shù)據(jù)結(jié)構(gòu)中的堆不是一個(gè)概念,堆區(qū)的分配方式倒是類似于鏈表踊赠。
棧區(qū)(stack area)
由系統(tǒng)自動(dòng)分配釋放呵扛,存放函數(shù)的參數(shù)值、局部變量的值等筐带。其操作方式類似于數(shù)據(jù)結(jié)構(gòu)中的棧今穿。
命令行參數(shù)區(qū)
存放命令行參數(shù)和環(huán)境變量的值,如通過(guò)main()函數(shù)傳遞的值伦籍。
C語(yǔ)言的內(nèi)存布局相對(duì)簡(jiǎn)單蓝晒,但也是最基本的。在編譯過(guò)程中就已經(jīng)確定了所有函數(shù)的地址(偏移地址)帖鸦。
C語(yǔ)言沒(méi)有對(duì)象的概念芝薇,那么變量的布局非常簡(jiǎn)單,固定作儿。除去全局洛二,靜態(tài)的變量分配在靜態(tài)數(shù)據(jù)區(qū),其它的臨時(shí)變量攻锰,參數(shù)等晾嘶,要么分配在棧區(qū)由系統(tǒng)自動(dòng)管理,要么由malloc()娶吞、calloc()垒迂、free()等函數(shù)由程序員管理分配在堆區(qū)。而變量本身的空間大小寝志,在分配時(shí)是相對(duì)簡(jiǎn)單并可以確定的娇斑。
C++對(duì)象的內(nèi)存布局
C++語(yǔ)言在C的基礎(chǔ)上添加了面向?qū)ο蟮母拍畈咛恚肓朔庋b材部,繼承,多態(tài)唯竹。而一個(gè)對(duì)象的內(nèi)存布局就相對(duì)于C語(yǔ)言的結(jié)構(gòu)體等在內(nèi)存的布局要復(fù)雜的多乐导。
在C++中,有兩種數(shù)據(jù)成員(class data members):static 和nonstatic,以及三種類成員函數(shù)(class member functions):static浸颓、nonstatic和virtual:
現(xiàn)在我們有一個(gè)類Base物臂,它包含了上面這5中類型的數(shù)據(jù)或函數(shù):
class Base
{
public:
Base(int i) :baseI(i){};
int getI(){ return baseI; }
static void countI(){};
virtual void print(void){ cout << "Base::print()"; }
virtual ~Base(){}
private:
int baseI;
static int baseS;
};
可以看到旺拉,對(duì)一個(gè)C++對(duì)象來(lái)說(shuō),它的內(nèi)存布局僅有虛表指針和非靜態(tài)成員棵磷,而其他的靜態(tài)成員蛾狗,成員函數(shù)(靜態(tài),非靜態(tài))仪媒,虛表等都是布局在類上的沉桌。
當(dāng)然,這是沒(méi)有考慮繼承的情況算吩。繼承情況下會(huì)更復(fù)雜一些留凭。可以參考(http://www.cnblogs.com/QG-whz/p/4909359.html)
OC對(duì)象的內(nèi)存布局
OC對(duì)象的內(nèi)存布局相對(duì)于C++更為復(fù)雜一些偎巢,出現(xiàn)了元類的概念:
簡(jiǎn)單來(lái)說(shuō)蔼夜,最左邊的是對(duì)象(Instance),中間的是類(Class)压昼,最右邊的是元類(Meta Class)求冷。屬性(包括父類)都保存在對(duì)象本身的存儲(chǔ)空間內(nèi);本類的實(shí)例方法保存在類中窍霞,本類的類方法保存在元類中遵倦。
那么對(duì)象的內(nèi)存布局如下:isa 指針指向其類,其余空間保存各級(jí)的屬性(ivar)
而類的內(nèi)存布局如下:
struct objc_class
{
struct objc_class* isa;
struct objc_class* super_class;
const char* name;
long version;
long info;
long instance_size;
struct objc_ivar_list* ivars;
struct objc_method_list** methodLists;
struct objc_cache* cache;
struct objc_protocol_list* protocols;
};
isa 指針指向其元類官撼,super_class指針指向其父類梧躺,此外還包含實(shí)例變量列表、方法列表傲绣、協(xié)議列表掠哥。
這里特別要指出的是實(shí)例變量列表中的實(shí)例變量的定義如下,它包含了變量的名稱秃诵、類型续搀、偏移等,但卻不包括變量的值-----值在對(duì)象而非類中:
struct objc_ivar {
char *ivar_name OBJC2_UNAVAILABLE;
char *ivar_type OBJC2_UNAVAILABLE;
int ivar_offset OBJC2_UNAVAILABLE;
#ifdef __LP64__
int space OBJC2_UNAVAILABLE;
#endif
}
參考文章:
C語(yǔ)言的代碼內(nèi)存布局詳解
C語(yǔ)言內(nèi)存模型
圖說(shuō)C++對(duì)象模型:對(duì)象內(nèi)存布局詳解
c++的類的內(nèi)存布局
OC優(yōu)缺點(diǎn)
OC對(duì)象的內(nèi)存布局
Objetive-C內(nèi)存布局