三種記憶體區間: global、stack、heap

變數會佔用記憶體,記憶體分為三個部份來存這些變數,分別是global、stack與heap。

global:

用來放全域變數、靜態變數(static)等等。

stack:

台灣正體中文稱為堆疊,大陸叫做棧。

區域變數、函式的參數與函式的位址等等,由系統管理,必須在編譯時期為已知。這些變數的回收會發生在它從堆疊pop出去的時候,因為個數、大小什麼的都是已知,所以系統知道怎麼進行配置與回收。

heap:

台灣正體中文稱為堆積,大陸叫做堆。

這裡的記憶體由使用者負責進行回收,配置則是由malloc或是new來負責。使用這裡的記憶體主要是用在編譯時期還不知道大小或個數的變數。例如說,你需要用一個陣列,這個陣列的大小要在執行的時候由使用者的輸入來決定,那你就只能使用動態配置,也就是把這個陣列配置在heap中。

 

stack與heap在記憶體中的配置狀況可以參考這張圖(http://www.geeksforgeeks.org/archives/14268):

stack and heap memory

我們也做一個小小的實驗吧:

address of a1 is 0x7fff4e62c554
address of a2 is 0x7fff4e62c550
address of a3 is 0x7fff4e62c54c
address of a4 is 0x7fff4e62c548
address of a5 is 0x7fff4e62c544
address of b1 is 0x7fff4e62c538
value of b1 is 0x417a010
address of b2 is 0x7fff4e62c530
value of b2 is 0x417a030
address of b3 is 0x7fff4e62c528
value of b3 is 0x417a050
address of b4 is 0x7fff4e62c520
value of b4 is 0x417a070
可以發現,a1到a5的記憶體位址是由大而小,也就是由高而低。而b1到b4的所指的位址(在heap)是由小而大,也就是由低而高,b1到b4本身的位址(在stack)則是由高而低。


參考資料來源:

http://blog.pfan.cn/xman/38791.html

http://antrash.pixnet.net/blog/post/70456505-stack-vs-heap%EF%BC%9A%E5%9F%B7%E8%A1%8C%E6%99%82%E6%9C%9F%E5%84%B2%E5%AD%98%E5%85%A9%E5%A4%A7%E8%A6%81%E8%A7%92

http://www.geeksforgeeks.org/archives/14268

 

13 comments

  1. 您好

    您說a1到a5的記憶體位址是由大而小 請問那a1到a5是存放在command-line argument這個區塊嗎?

    另個問題是 global是指stack和heap以外的地方嗎? 包含command-line argument,uninitialized data,initialized data,text 這四塊嗎?
    謝謝

  2. 請問stack跟heap會有大小限制嗎?

    比如只能存2,147,483,647這麼多個,還是依據使用者執行裝置的記憶體大小為主?

  3. 請問在 Java 中也是同道理嗎?

    因為我 new 了四個物件並印出之後,記憶體位址看起來是亂數產生。

  4. 您好,

    不好意思…

    想請問一下您是怎麼把stack裡local variable的資料印出來的?

  5. @Iaa :

    你印的那個叫hashcode,不是記憶體位置…..

    JAVA沒有辦法像C++那樣可以知道某個變數的記憶體位置在哪….

  6. stack 是用來存放已知生命週期的變數或函式資訊,如果今天我在main中寫一個

    int a;   不給予初值,這個記憶體空間是在heap區還是stack區???

  7. Pretty section of content. I just stumbled upon your blog and in accession capital to assert that I get actually enjoyed account your blog posts. Any way I’ll be subscribing to your feeds and even I achievement you access consistently rapidly.

Leave a Reply

你的電子郵件位址並不會被公開。 必要欄位標記為 *