閱讀筆記九——java虛擬機堆棧

虛擬機棧(線程棧)與 堆(Heap)線程

爲更好的理解Java線程棧和堆,咱們簡單的認爲Java內存模型把Java虛擬機內部劃分爲線程棧和堆。這張圖演示了Java內存模型的邏輯視圖。對象

 

每個運行在Java虛擬機裏的線程都擁有本身的線程棧。這個線程棧包含了這個線程調用的方法當前執行點相關的信息。一個線程僅能訪問本身的線程棧。一個線程建立的本地變量對其它線程不可見,僅本身可見。即便兩個線程執行一樣的代碼,這兩個線程任然在在本身的線程棧中的代碼來建立本地變量。所以,每一個線程擁有每一個本地變量的獨有版本。內存

全部原始類型的本地變量都存放在線程棧上,所以對其它線程不可見。一個線程可能向另外一個線程傳遞一個原始類型變量的拷貝,可是它不能共享這個原始類型變量自身。虛擬機

堆上包含在Java程序中建立的全部對象,不管是哪個對象建立的。這包括原始類型的對象版本。若是一個對象被建立而後賦值給一個局部變量,或者用來做爲另外一個對象的成員變量,這個對象任然是存放在堆上。變量

下面這張圖演示了調用棧和本地變量存放在線程棧上,對象存放在堆上。引用

 

一個本地變量多是原始類型,在這種狀況下,它老是「呆在」線程棧上。程序

一個本地變量也多是指向一個對象的一個引用。在這種狀況下,引用(這個本地變量)存放在線程棧上,可是對象自己存放在堆上。方法

一個對象可能包含方法,這些方法可能包含本地變量。這些本地變量任然存放在線程棧上,即便這些方法所屬的對象存放在堆上。版本

一個對象的成員變量可能隨着這個對象自身存放在堆上。無論這個成員變量是原始類型仍是引用類型。模型

靜態成員變量跟隨着類定義一塊兒也存放在堆上。

存放在堆上的對象能夠被全部持有對這個對象引用的線程訪問。當一個線程能夠訪問一個對象時,它也能夠訪問這個對象的成員變量。若是兩個線程同時調用同一個對象上的同一個方法,它們將會都訪問這個對象的成員變量,可是每個線程都擁有這個本地變量的私有拷貝。

下圖演示了上面提到的點:

 

兩個線程擁有一些列的本地變量。其中一個本地變量(Local Variable 2)執行堆上的一個共享對象(Object 3)。這兩個線程分別擁有同一個對象的不一樣引用。這些引用都是本地變量,所以存放在各自線程的線程棧上。這兩個不一樣的引用指向堆上同一個對象。

注意,這個共享對象(Object 3)持有Object2和Object4一個引用做爲其成員變量(如圖中Object3指向Object2和Object4的箭頭)。經過在Object3中這些成員變量引用,這兩個線程就能夠訪問Object2和Object4。

相關文章
相關標籤/搜索