物件模型是物件導向程式設計語言的一個重要方面,它會直接影響物件導向語言編寫程式的運行機制及對內在的使用機制,因此瞭解物件模型是進行程式最佳化 的基礎。分析一般意義上程式中的資料在記憶體中的分布,以及程式使用的不同種類的記憶體等基本的概念。瞭解對象的生命週期,以及對象的記憶體布局。只有通過深入 的學習C++物件模型,才能避免程式開發中一些不易察覺的記憶體錯誤 。從而達到改善程式效能,提高程式的品質。
程式使用記憶體區
一 個種序佔用的記憶體區一般分為,全域(靜態)資料區,常量資料區,代碼區,棧,堆,我們所編寫的程式就放在代碼區中,而程式的資料要根所相應的資料類型,存 儲至不同的記憶體區中,在C++語言中,資料有不同的分類方法,例如常量和變數,全域資料和局部資料,以及待用資料和非待用資料.另外,還有程式運行過程中 動態產生和釋放的資料,這些資料放在不同的資料區中。
全域(靜態)資料區儲存全域變數及靜態變數(包括全域靜態變數和局部靜態變數)。
常量資料區中儲存程式中的常量字串等。
棧中儲存自動變數或者局部變數,以及傳遞的函數參數等,而堆是使用者程式控制的儲存區,儲存動態產生的資料。
通過Memory.cpp來測試可以清晰看出,記憶體區的資料的存放
#include <stdio.h>
#include <stdlib.h>
int nGlobal = 100;
int main(void )
...{
char *pLocalString1 = "LocalString1";
const char *pLocalString2 = "LocalString2";
static int nLocalStatic = 100;
int nLocal = 1;
const int nLocalConst = 20;
int *pNew = new int[5];
char *pMalloc = (char *)malloc(1);
//全域變數(nGlobal)、靜態變數和局部的靜態變數(nLocalStatic)
printf("global variable: 0x%x ", &nGlobal);
printf("static variable: 0x%x ", &nLocalStatic);
printf("local expression 1: 0x%x ", pLocalString1);
printf("local expression (const) : 0x%x ", pLocalString2);
//堆記憶體
printf(" ");
printf("new: 0x%x ", pNew);
printf("malloc: 0x%x ", pMalloc);
printf(" ");
printf("local pointer(pNew): 0x%x ", &pNew);
printf("local pointer(pLocalString2): 0x%x ", &pLocalString2);
printf("local pointer(pLocalString1): 0x%x ", &pLocalString1);
printf("local variable(nLocal): 0x%x ", &nLocal);
printf("local pointer(pMalloc): 0x%x ", &pMalloc);
printf("local const variable: 0x%x ", &nLocalConst);
return 0;
}
輸出為:
global variable: 0x417000
static variable: 0x417004
local expression 1: 0x4158d4
local expression (const) : 0x4158c4
new: 0x32a10
malloc: 0x32a50
//邊界對齊通過New申請了5個整數需要的記憶體,通過 malloc申請了1個位元組。這裡的地址相差32個位元組,如果按正常算應該是20個位元組為0x14,malloc申請地址應該從new後的20個位元組 32a24開始,但佔據32個位元組的記憶體(0x32a10~0x32a50),即在記憶體配置時按16個位元組對齊。
local pointer(pNew): 0x13ff30
local pointer(pLocalString2): 0x13ff54
local pointer(pLocalString1): 0x13ff60
local variable(nLocal): 0x13ff48
local pointer(pMalloc): 0x13ff24
local const variable: 0x13ff3c
記憶體對齊雖然浪費一些記憶體,但由於CPU在對齊下運行比較快,簡化了處理器和儲存空間系統之間介面的硬體設計。如,假設處理器總是從存 儲器中取8個位元組出來,則地址必須為8的倍數。如果我們能合保證所有的double都將它們的地址對齊成8的倍數,那麼就可以用一個儲存空間操作來讀或寫值 了。否則,我們可能需要執行兩次儲存空間訪問,因為對象可能分放在兩個8位元組儲存空間塊中。