對於堆疊的一些理解
本文以CHIPSE公司的CSU18MX86為例,對堆疊做一個簡單的知識整理。
該SOC總共由三個堆疊,PC, STATUS, WORK。其中 PC是硬體堆疊, STATUS, WORK是軟體堆疊實現。
那麼,硬體堆疊和軟體堆疊有什麼區別呢?
然後,堆和棧有什麼區別呢?
棧記憶體:棧記憶體首先是一片記憶體區域,儲存的都是區域性變數,凡是定義在方法中的都是區域性變數(方法外的是全域性變數),for迴圈內部定義的也是區域性變數,是先載入函式才能進行區域性變數的定義,所以方法先進棧,然後再定義變數,變數有自己的作用域,一旦離開作用域,變數就會被釋放。棧記憶體的更新速度很快,因為區域性變數的生命週期都很短。
堆記憶體:儲存的是陣列和物件(其實陣列就是物件),凡是new建立的都是在堆中,堆中存放的都是實體(物件),實體用於封裝資料,而且是封裝多個(實體的多個屬性),如果一個數據消失,這個實體也沒有消失,還可以用,所以堆是不會隨時釋放的,但是棧不一樣,棧裡存放的都是單個變數,變數被釋放了,那就沒有了。堆裡的實體雖然不會被釋放,但是會被當成垃圾,Java有垃圾回收機制不定時的收取。
舉個例子:
int [] arr=new int [3];在記憶體中是怎麼被定義的:
主函式先進棧,在棧中定義一個變數arr,接下來為arr賦值,但是右邊不是一個具體值,是一個實體。實體建立在堆裡,在堆裡首先通過new關鍵字開闢一個空間,記憶體在儲存資料的時候都是通過地址來體現的,地址是一塊連續的二進位制,然後給這個實體分配一個記憶體地址。陣列都是有一個索引,陣列這個實體在堆記憶體中產生之後每一個空間都會進行預設的初始化(這是堆記憶體的特點,未初始化的資料是不能用的,但在堆裡是可以用的,因為初始化過了,但是在棧裡沒有),不同的型別初始化的值不一樣。所以堆和棧裡就建立了變數和實體:
那麼堆和棧是怎麼聯絡起來的呢?
我們剛剛說過給堆分配了一個地址,把堆的地址賦給arr,arr就通過地址指向了陣列。所以arr想操縱陣列時,就通過地址,而不是直接把實體都賦給它。這種我們不再叫他基本資料型別,而叫引用資料型別。稱為arr引用了堆記憶體當中的實體。
所以堆與棧的區別很明顯:
1.棧記憶體儲存的是區域性變數而堆記憶體儲存的是實體;
2.棧記憶體的更新速度要快於堆記憶體,因為區域性變數的生命週期很短;
3.棧記憶體存放的變數生命週期一旦結束就會被釋放,而堆記憶體存放的實體會被垃圾回收機制不定時的回收。
部分轉載於:https://blog.csdn.net/pt666/article/details/70876410 感謝博主分享!!