按照老版操作系統來學習,內存對於程序來講分四區。分別是 代碼區,靜態區,棧,堆。
由上面程序執行的結果可知:
貌似結果就是 靜態代碼堆棧
靜態區存放的是程序中所有靜態變量和常量的值。靜態區的大小是程序加載到內存之后就固定的,不會再發生改變。
代碼區中存放的是程序中的代碼,不能修改它的值,只能通過指針或者變量名來使用函數。【當然強行修改是被允許的但是可能發生未知錯誤。】
堆是一塊很大的區域,通常情況下是4G的大小,(這個數字通常情況下是虛擬的,但是可以利用現代操作系統來利用硬盤模擬出來這么一塊兒空間,因為我們隨便開幾個程序這就一下把內存撐死了。所以這個 4G是一個虛擬的情況,我們編程的時候就考慮這是一個4G的很大空間就可以了,然后 要記得自己分配的空間及時還回去。)
棧,棧對於不同的操作系統來講,其大小不固定,有大有小,通常情況下在4k或者8k左右,64k就頂天了。但是 不同的是:棧對於一個線程來講,就有一個棧,如果一個進程有4個線程,那么這個 線程區域就有4個棧。
對於整個分配過程來講,可以看到我們是從地址的高位開始往下分配了靜態區域,代碼區域,堆,棧,所以可以想見:對於里面的每一個東西來講,分配都是從上到下的
根據這個結果來分析一下對於內存的分配關系:
堆這里不太敢說,但是對於棧來講,先進后出,從下面入,下面出。
並且它的釋放是按照,代碼塊兒的形式釋放的,按照取地址的方式取得具體的某一個數字的值的。
我們的驗證結果跟這個圖還是基本一致的,除了 靜態區和代碼區多少有點出入以外。棧的上面是棧底,我們一行一行往里面寫數據,然后在釋放數據。堆里面不斷地開辟空間,進行使用。想到了之前我們說的。在windows里面內存使用的大端對齊,拿我們的程序的高位對內存的低位。而對於某些大型服務器的系統來講,是小端對齊。拿程序的低位對應內存的低位。
既然知道了內存的分配,那么希望我們所寫的代碼盡量少的使用內存。
所以在編程的時候:這樣寫:Char[9].總感覺比Char[10]要省一個字節。那么真的如此么?
於是跑了一段這樣的代碼:
我的系統得到的結果是每次都會增加4k。
按照視頻的講解的思路就是:當我們的程序在malloc的時候,都會開辟32k大小的一塊空間,每32k上面有4k大小的內存頁,我們申請了一段內存,就先可着頭一個4k大小的內存頁使,當用完當前這個內存頁之后,從32k的空間上拿走下一個4k的內存頁,直到當前的32k被用完,此時,去向操作系統申請下一塊32k大小的內存。如此循環,所以本質上我們這個要走的多少一個字節,反而有點兒沒有必要。反而更重要的點在於用完了要及時把我們malloc的堆及時得free掉。比較靠譜。