2017-06-18 73 views
2

而不是堆棧,隊列也可以用於它。爲什麼JVM使用「堆棧」作爲局部變量和調用內存管理方法?我已經谷歌我的問題,但沒有得到完全答案。JVM:它用於JVM作爲存儲本地人的首選選項的「堆棧」有什麼好處?

+3

因爲堆棧是LIFO而隊列是FIFO。隊列中的「偉大的事情」是什麼?爲什麼更喜歡隊列堆棧? –

+3

謝謝@VinceEmigh我知道,我想知道在JVM中,LIFO是更好的選擇而不是FIFO嗎? –

+1

從另一個方法調用方法的模型的替代方法是什麼? –

回答

6

由於@Vince在評論中提到,堆棧是後進先出(LIFO),隊列是先進先出(FIFO)列表。

當方法被調用時,他們通常有一個序列像這樣,

  • 方法M1調用方法M2
  • 方法調用M2 M3方法
  • 方法調用M3 M4方法
  • ...

當方法m4返回時,執行返回到方法m3。

當方法m3返回時,執行返回方法m2,依此類推。

最後,方法m1完成其執行。

請注意,方法m1是第一個被調用,但最後一個完成其執行。因此,在堆棧上存儲方法調用有利於內存管理(因爲堆棧是LIFO)。

局部變量在方法中聲明和定義,因此也存儲在堆棧中。

4

在Java中,當執行達到}字符時,自從匹配的{字符超出範圍之後聲明的任何局部變量以及用於它們的內存(引用或原始變量,而不是對象)都可以重用。但匹配的{字符是最近遇到的{,尚未與}字符匹配。

因此,變量超出了「最近創建」範圍的範圍。最近宣佈的那些將是首先消失的那些。那些最早被宣佈的將是最後消失的那些。

你不能用隊列來做到這一點。局部變量需要處於「後進先出」結構,如堆棧。

+0

感謝有價值的信息... @達伍德伊本賈巴爾 –

1

此問題與Java或JVM無關。或者說,對於JVM而言,並不是特定的,而是質疑幾乎所有編程語言都實現的Call Stack的概念。

如果你學習方法是如何調用的工作,特別是如何從一個方法調用返回的處理,以及如何局部變量都存儲調用返回的信息,你會很快發現呼叫隊列將使沒有任何意義。

+0

多麼美妙的答案,Idk聰明誰upvotes答案說*去學習和搜索* – Yahya

2

這是線程代碼流的一個基本的,不可避免的屬性,最後輸入的方法將是第一個返回的方法。即使在例外的情況下,如果有多於一種方法可能會被留下,它將是最後的方法。因此,一個LIFO數據結構是只有的選擇,而不僅僅是「更好」的一個。

也就是說,這種堆棧是邏輯邏輯概念,而不是實現要求。該specification states

每個Java虛擬機線程都有一個私人Java虛擬機堆,同時爲線程創建。 Java虛擬機堆棧存儲幀(§2.6)。 Java虛擬機堆棧類似於傳統語言(如C語言)的堆棧:它包含局部變量和部分結果,並在方法調用和返回中扮演角色。由於除了推送和彈出框架之外,Java虛擬機堆棧從不直接操作,所以可能會分配堆棧。 Java虛擬機堆棧的內存不需要是連續的。

最後兩句提示JVM如何實現該堆棧的自由。事實上,像堆分配棧幀的鏈表可能是可能的。然而,提供高效的「推送」和「流行」操作,在同一端添加和刪除幀至關重要。

萬一Stack Frame需要澄清的術語:

用於存儲數據和部分結果,以及執行動態鏈接,對於方法返回值,並調度異常。

每次調用某個方法時都會創建一個新框架。框架在其方法調用完成時被銷燬,無論該框架是正常還是突然(它引發未捕獲的異常)。幀是從創建幀的線程的Java虛擬機堆棧(§2.5.2)分配的。

這種關係,即在每個方法調用中創建和推送新框架以及在方法完成時彈出並銷燬它的需求,決定了Java虛擬機堆棧如何工作。