1. 程式人生 > >java建立物件記憶體分配空間及其原理一

java建立物件記憶體分配空間及其原理一

          一直想寫關於java物件的文章,一直拖著就等到了現在。其實,當你真正走上程式設計師這條道路的正軌時,程式碼對於我們來說,已經不再是問題了。但是,假如我問你原理,你真的能知道其一二嗎?

         網上關於java的文章琳琅滿目,但真的講到原理這東西,很多都是晦澀難懂,有點小複雜。所以,我將用通俗易懂的語言去講解一些原理性的東西。

         話不多說,進入正題。

         我們學習java必定知道建立物件,然後我們通過這個物件拿變數,拿方法。但是,這裡面的java虛擬機器到底是怎麼準確拿到這些東西的呢?首先,我們要先搞明白,關於計算機,我們玩的都是地址,地址很重要。例如,C語言,我們玩的就是指標,講俗點,指標就是地址。首先,jvm為我們分配三塊重要的記憶體空間,棧記憶體,堆記憶體以及方法區。這裡我只講解方法區。方法區,也就是入口,所有要用到的東西,都要現在這裡提前載入完。我先舉建立一個物件的情況,如Person p = new Person( )。當我們編寫完java檔案,要編譯成.class檔案,然後 .class檔案載入進方法區。每個程式都有一個入口函式,就講main方法吧。當.class檔案載入進方法區的時候,main主函式就要壓進棧記憶體了。當main主函式壓進棧記憶體後,jvm就會去找引用變數p,但是p是什麼東西呢?不知道。恰好,引用變數前,已經宣告是person了。所以jvm會將person類載入進方法區,那現在好辦事了。我們通過new Person(),就到堆記憶體了。在堆記憶體通過new開闢一片空間,但你要明確,這片空間本來就是有地址的。記憶體中只是提供一塊地方給你用,不一定代表他就是是無名地哦。我們知道,類是屬性和行為的集合,屬性包括有基本資料型別,他們都有預設值,只要在我們沒有在使用前賦值,你要記住,他們都是有預設值的。繼續,通過new之後,堆記憶體開闢的空間的地址就指向了引用變數,所以,現在我們就可以去使用該物件的成員變數和成員方法。

        整個物件建立過程我們已經很清楚了。但是這只是引用了堆記憶體空間地址而已,我們還要使用該物件成員方法那原理又是怎樣呢?上述我們知道,我們引用變數拿到了物件的地址,所以我們要呼叫物件的方法當然也是通過該地址。不過,我們現在是在棧記憶體中操作。我們在棧記憶體也開闢一片空間,我們俗稱方法壓進棧,此方法就是該物件的方法。當此方法呼叫完後,就會被釋放掉,俗稱彈棧,即它會彈出棧記憶體,沒用了,下次再使用該方法時,再會執行進棧和彈棧的操作。

      至此,我們便知道了建立物件、使用成員變數和成員方法的原理了,但是我們不可能物件地址一直指向引用變數。是的,所以在整個應用程式執行完畢後,主函式方法也會彈出棧,此時的引用指向也會想風箏斷了弦一樣,沒用人牽著它。此時,有個重要的人物要出現------垃圾回收(GC)。jvm自己有垃圾回收機制,它會不斷在堆記憶體中巡視,當它發現使用過的物件地址沒有被引用時,它就會將此記憶體回收掉,避免資源的浪費。java虛擬機器還是很方便的。如果是C語言,你的老師可能會經常提醒你,記得回收刪除不必要的引用。但是,jvm就沒這個問題,我們只需要做我們該做的事情就ok了。

     同理,當我們建立兩個物件的時候,其原理一模一樣。就是同樣進行上述操作。主要要區別的是,我們建立兩個相同物件方法區該怎麼載入呢?就講上述的Person類,我們方法區只去載入一次就可以用多次,不會像堆記憶體那樣,不斷開闢空間去引用地址。