“堆棧”:到底什麼事“堆”,什麼是“棧”?

是時候來看看對象和方法的生存空間了——想要了解面向對象,不知道方法和對象放在哪裡是一件很尷尬的事情——畢竟我們還是要面對垃圾收集器的,想要讓垃圾收集器幫你做更多的事情,我們就得一定程度上了解它的工作機制,了解方法和對象存放在哪裡,否則的話,你就又要寫出一個不堪一擊的程序來了!

我們在前邊的課程當中已經基本地提過堆的概念,沒錯,對象(實例)是放在堆上的——我將它形像地描述為“垃圾堆”。

被堆在棧中的方法

這個描述的標題看上去好像有點問題,但確實是形象的,方法都被放在棧當中,包括方法當中的局部變量。

這就是為什麼有時候局部變量又被稱作“棧變量”。

方法會被一個一個地壓入棧當中,先被調用的會被壓在最裡邊,最後被調用的則在棧頂,然後執行完畢的方法會從棧頂被彈出——我們來舉個栗子:

還是熟悉的武器問題,當我們調用 reloadAndFire() 的時候,這個方法就被壓入棧頂——這個時候其實棧當中也就只有它一個,它調用了 fire () 方法,那麼 fire 被壓入棧頂,而 reloadAndFire() 由於還沒有執行完畢,就被壓到了下邊,然後 fire () 執行完畢了,就會被彈出棧頂, reloadAndFire() 又回到了原來的位置,那麼系統就會繼續執行它,然後就調用了 reload() 方法,然後又是 fire() ,最後 reloadAndFire() 執行完畢,也被彈出。

那在方法裡聲明的實例呢?

我們說過關於引用的內容,不論在任何地方創建實例,實例都是存在於堆上的,局部變量手裡握著的只能是遙控器。

實例裡的變量

說到實例,它裡邊的變量是跟著實例一起住在堆上的,他們的生存週期就要比局部變量長了很多——隨著實例生死。所以,我們在方法當中調用實例的變量,但方法被彈出實例變量也不會就此消失,而是等到實例被回收的時候才會跟著實例魂歸田雞。

創建一個對象

這個時候我們就能詳細的描述創建一個對象的全過程了:

  1. 聲明了儲存器,把它標記為某個實例的引用類型;
  2. 創建一個對象,它存在於堆
  3. 將堆上的對象與儲存器中的引用連接起來——給引用里傳入對象的地址。

 

 

 

由...出版 R0uter

如非聲明,本人所著文章均為原創手打,轉載請註明本頁面鏈接和我的名字。

發表評論

您的電子郵件地址不會被公開. 必填字段標 *