4、JVM之棧與棧幀

棧:

一、又名堆棧,它是一種運算受限的線性表。其限制是僅容許在表的一端進行插入和刪除運算。這一端被稱爲棧頂,相對地,把 另外一端稱爲棧底。其特性是先進後出。數據結構

二、棧是線程私有的,生命週期跟線程相同,當建立一個線程時,同時會建立一個棧,棧的大小和深度都是固定的。jvm

三、方法參數列表中的變量,方法體中的基本數據類型的變量和引用數據類型的引用都存放在棧中,成員變量和對象自己不存放在棧中。運行時,成員函數的局部變量引用也存放在棧中。函數

四、棧的變量隨着變量做用域的結束而釋放,不須要jvm垃圾回收機制回收。優化

五、棧不是全局共享的,每一個線程建立一個棧,該線程只能訪問其對應的棧數據線程

六、棧內存的大小是在編譯期就肯定了的。設計

棧幀:

一、一個棧中能夠有多個棧幀,棧幀隨着方法的調用而建立,隨着方法的結束而消亡。該棧幀中存儲該方法中的變量,原則上各個棧幀之間的數據是不能共享的,可是在方法間調用時,jvm會將一方法的返回值賦值給調用它的棧幀中。每個方法調用,就是一個壓棧的過程,每一個方法的結束就是一個彈棧的過程。壓棧都將會將該棧幀置於棧頂,每一個棧不會同時操做多個棧幀,只會操做棧頂,當棧頂操做結束時,會將該棧幀彈出,同時會釋放該棧幀內存,其下一個棧幀將變爲棧頂。棧內存歸屬於單個線程,每一個線程都會有一個棧內存,其存儲的變量只能在其所屬線程中可見,即棧內存能夠理解成線程的私有內存。指針

二、棧中的優化,其一是當局部變量賦值時,會在棧空間中找其對應的值,當有該值時,將該值指向變量,當沒有該值時,建立一個該值,而後再指向該變量,例如:int a = 1, int b = 1, b = 2; 其二是棧中的變量隨着方法的調用而建立,當方法執行結束後,jvm會自動釋放內存。對象

棧幀的組成部分:

一、局部變量表:是一組變量值的存儲空間,用呀存放方法參數和局部變量,虛擬機經過索引定位的方式使用局部變量表。索引

二、操做數棧:常稱爲操做數棧,是一個後入先出棧。方法執行中進行算術運算或者是調用其餘的方法進行參數傳遞的時候是經過操做數棧進行的。在概念模型中,兩個棧幀是相互獨立的。可是大多數虛擬機的實現都會進行優化,令兩個棧幀出現一部分重疊。令下面的部分操做數棧與上面的局部變量表重疊在一塊,這樣在方法調用的時候能夠共用一部分數據,無需進行額外的參數複製傳遞。生命週期

三、動態鏈接: 在說明什麼是動態鏈接以前先看看方法的大概調用過程,首先在虛擬機運行的時候,運行時常量池會保存大量的符號引用,這些符號引用能夠當作是每一個方法的間接引用,若是表明棧幀A的方法想調用表明棧幀B的方法,那麼這個虛擬機的方法調用指令就會以B方法的符號引用做爲參數,可是由於符號引用並非直接指向表明B方法的內存位置,因此在調用以前還必需要將符號引用轉換爲直接引用,而後經過直接引用才能夠訪問到真正的方法,這時候就有一點須要注意,若是符號引用是在類加載階段或者第一次使用的時候轉化爲直接應用,那麼這種轉換成爲靜態解析,若是是在運行期間轉換爲直接引用,那麼這種轉換就成爲動態鏈接

四、方法返回地址:方法的返回分爲兩種狀況,一種是正常退出,退出後會根據方法的定義來決定是否要傳返回值給上層的調用者,一種是異常致使的方法結束,這種狀況是不會傳返回值給上層的調用方法.不過不管是那種方式的方法結束,在退出當前方法時都會跳轉到當前方法被調用的位置,若是方法是正常退出的,則調用者的PC計數器的值就能夠做爲返回地址,若是是由於異常退出的,則是須要經過異常處理表來肯定.在方法的的一次調用就對應着棧幀在虛擬機棧中的一次入棧出棧操做,所以方法退出時可能作的事情包括,恢復上層方法的局部變量表以及操做數棧,若是有返回值的話,就把返回值壓入到調用者棧幀的操做數棧中,還會把PC計數器的值調整爲方法調用入口的下一條指令。

棧的優勢:

一、棧幀內存數據共享:棧幀之間數據不能共享,可是同一個棧幀內的數據是能夠共享的,這樣設計是爲了減少內存消耗,例如:int a = 1, int b= 1時,前面定義了a=1,a和1都在棧內存內,若是再定義一個b=1,此時將b放入棧內存,而後查找棧內存中是否有1,若是有則b指向1。若是再給b賦值2,則在棧內存中查找是否有2,若是沒有就在棧內存中放一個2,而後b指向2。也就是若是常量在棧內存中,就將變量指向該常量,若是沒有就在該棧內存增長一個該常量,並將變量指向該常量。

二、存取速度比堆要快,僅次於寄存器。速度快之一是棧在編譯器就申請好了內存空間,因此在運行時不須要申請內存大小,節約了時間,其二是棧是機器系統提供的數據結構,計算機會在底層對棧提供支持:分配專門的寄存器存放棧的地址,壓棧出棧都有專門的指令執行,這就決定了棧的效率比較高。其三是訪問時間,訪問堆的一個具體單元,須要兩次訪問內存,第一次得取得指針,第二次纔是真正得數據,而棧只需訪問一次。

棧的缺點:

存在棧的數據大小和生存期必須是肯定的,缺少靈活性。當棧在運行執行程序時,發現棧內存不夠,不會動態的去申請內存,以致於致使程序報錯,因此靈活性較差。

相關文章
相關標籤/搜索