1. 程式人生 > >【Big Data 每日一題20181111】為什麼有棧記憶體和堆記憶體之分

【Big Data 每日一題20181111】為什麼有棧記憶體和堆記憶體之分

為什麼有棧記憶體和堆記憶體之分?

        陣列引用變數只是一個引用,這個引用變數可以指向任何有效的記憶體,只有當該引用指向有效記憶體,才可以通過該陣列變數來訪問陣列。

       實際的陣列物件被儲存在堆(heap)記憶體中;如果引用該陣列物件引用變數是一個區域性變數,那麼它被儲存在棧(stack)記憶體中。

        當一個方法執行時,每個方法都會建立自己的記憶體棧,在這個方法內定義的變數將會逐個放入這塊棧記憶體裡,隨著方法的執行結束,這個方法的記憶體棧也將自然銷燬了。因此,所有在方法中定義的變數都是放在棧記憶體中的;當我們在程式中建立一個物件時,這個物件將被儲存到執行時資料區中,以便反覆利用(因為物件的建立成本通常較大),這個執行時資料區就是堆記憶體。堆記憶體中的物件不會隨方法的結束而銷燬,即使方法結束後,這個物件還可能被另一個引用變數所引用(方法的引數傳遞時很常見),則這個物件依然不會被銷燬。只有當一個物件沒有任何引用變數引用它時,系統的垃圾回收機制才會在合適的時候回收它。

       如果堆記憶體中陣列不再有任何引用變數指向自己,則這個陣列將成為垃圾,該陣列所佔的記憶體將會被系統的垃圾回收機制回收。因此,為了讓垃圾回收機制回收一個數組所佔的記憶體空間,則可以將該陣列變數賦為null,也就切斷了陣列引用變數和實際陣列之間的引用關係,實際陣列也就成了垃圾。

陣列是一種引用資料型別,陣列引用變數只是一個引用,陣列元素和陣列變數在記憶體裡是分開存放的。下面將深入介紹陣列在記憶體中的執行機制。

陣列引用變數只是一個引用,這個引用變數可以指向任何有效的記憶體,只有當該引用指向有效記憶體後,才可通過該陣列變數來訪問陣列元素。

與所有引用變數相同的是,引用變數是訪問真實物件的根本方式。也就是說,如果我們希望在程式中訪問陣列,則只能通過這個陣列的引用變數來訪問它。

實際的陣列元素被儲存在堆(heap)記憶體中;陣列引用變數是一個引用型別的變數,被儲存在棧(stack)記憶體中。陣列在記憶體中的儲存示意圖如圖4.2所示: 
圖4.2 陣列在記憶體中的儲存示意圖 
如果需要訪問圖4.2中堆記憶體中的陣列元素,程式中只能通過p[index]的形式實現。也就是說,陣列引用變數是訪問堆記憶體中陣列元素的唯一方式。