1. 程式人生 > >java虛擬機器棧番外篇

java虛擬機器棧番外篇

晉-陶淵明《五柳先生傳》:[好讀書,不求甚解],原指讀書只求領會主旨,不死摳字眼。現多指滿足於瞭解個大概,不作深入理解。

不求甚解,好嗎?

在上一篇文章講解java虛擬機器棧的時候,我有一個困惑的問題,大概是:

比如int a = 5,那麼它是如何儲存的,我們先來看這個程式碼,int代表基本資料型別整型,a可以叫做一個變數,更加準確的來說,它是一個變數名稱a,這個a是我們程式設計師編寫程式碼的時候寫給我們自己看的,然後給這個變數賦值5,這個5就是具體的變數值了。

那麼當其編譯,並載入到記憶體的時候發生了什麼呢?我們一步步來,首先就是會向記憶體申請分配一塊記憶體,這塊記憶體多大呢?因為int是佔四個位元組,也就是32位,所以應該向記憶體分配一個32記憶體大小的空間,然後將這個5轉換成二進位制,然後存在這個32位的空間。

我們繼續深入,我們知道了記憶體大小空間,那麼我們這裡只說向記憶體申請分配空間,那麼是什麼記憶體呢?我們知道jvm記憶體空間有好幾個區域,嗯,這個我們也知道,是棧記憶體空間。

那麼這個棧記憶體空間又是什麼呢?這個棧準確來說十java虛擬機器棧,是隨執行緒而生,而這個java虛擬機器棧中隨著方法的呼叫又會產生一個棧幀隨之入棧,然後由方法的結束進而出棧,而這個棧幀中又包含著區域性變量表,運算元棧,動態連結和方法返回地址等。

那麼我們說它儲存在棧記憶體中,而這個java虛擬機器棧又有這麼幾部分,那麼它到底是存放在哪呢?區域性變量表?還是運算元棧,亦或者是其他。首先我們來看,這個區域性變量表是存放什麼的?

區域性變量表是用來存放方法執行的引數和方法內部定義的區域性變數,那好,現在我們的這個int a = 5就是定義在一個方法內的,那麼它自然是一個區域性變數,這麼一來就是存放在區域性變量表了,不過,存放在區域性變量表的到底是這個a還是5呢?

好了,到這裡就是我的疑問了!

對於這個5倒是好理解,就是一個具體的數值,存放的話是將其轉成二進位制資料存放在相應的記憶體空間,那麼這個a是什麼?從字面意思上看就是一個字母a,我們之所以定義這個a,大概就是給這個變數起個名字,當我們說a的時候,我們就知道指的就是這個5,這就好比你叫張三,我們叫張三其實指的就是你這個具體的人。

那麼,關乎到儲存的話又是怎麼回事呢?比如這有一片住宅區,有幾間房子,然後給你“張三”分配一間房子,你住進去了,實際上住進去的是你這個人,這就好比現在我們在區域性變量表(住宅區)申請一塊記憶體(一間房子),然後將這個5(你這個人)存進去,而這個a(你的名字張三)就代指這個5(你這個人)。

這個時候我們可能會說,“那個那個,,張三,你的房子”,對我們會說張三的房子,要是給這個房子打上一個標籤,那就是“張三的”,給這個房子起個名字的話,對,就叫“張三”

也就是說對於int a = 5,要儲存了,來來來,趕緊在區域性變量表中申請一塊記憶體,把這個5放進去,那這塊記憶體空間做個標識吧,叫啥呢?嗯,就叫做a。

這是基本資料型別,那如果是引用資料型別呢?比如String s = new String()
那麼這個是存麼儲存的呢?我門知道物件例項是存放在堆記憶體,也就是在堆中申請一塊記憶體空間存放這個字串物件例項,那麼這裡的這個s是怎麼回事呢?這個時候也會在棧記憶體中申請一塊記憶體空間,儲存啥呢?儲存存放堆中字串例項物件那一塊記憶體空間的首地址,而在這棧中申請的這塊記憶體空間你就可以看做是s。

也就是說對於基本資料型別是在棧記憶體空間申請記憶體空間存放具體的數值,這塊記憶體空間我們怎麼去表示它,就可以用具體的變數名稱去表示,而對於引用資料型別, 在棧中申請的這塊記憶體空間存放的則是例項物件在堆中所在記憶體空間的首地址,而這個棧中的這塊記憶體就可以用物件引用表示!

像int a = 5和String s = new String()中的a和s(又叫做物件引用)都是一個名稱,我們上面所說用這些名稱來表示棧中分配的記憶體空間,但是要說這些名稱到底是個什麼玩意,我覺得他們實際上是這些棧中分配的記憶體空間的地址!

因為程式中的名稱都是給程式設計師看的,而JVM操作的都是“地址”!