標籤:語言 reference ring jvm 重要 也會 size http string
Java中對象的訪問
JAVA是物件導向的語言,那麼在JAVA虛擬機器中,存在非常多的對象,對象訪問是無處不在的。即時是最簡單的訪問,也會涉及到JAVA棧、JAVA堆、方法區這三個非常重要的記憶體地區之間的關聯關係。
比如:
Object obj = new Object();
其中,“Object obj”這部分語義作為一個reference類型資料出現,將儲存到JAVA棧的本地變數表中。new Object()將產生一個實體物件,儲存在JAVA堆中,包含了Object類型的所有執行個體資料值(對象中各個欄位的資料)的結構化記憶體,根據具體類型以及虛擬機器實現的對象記憶體布局的不同,這塊記憶體的長度是不固定的。另外,在JAVA堆中還必須包含能尋找到此物件類型資料(如物件類型、父類、實現介面、方法等)的地址資訊,這些類型資料存放區在方法區中。
由於reference類型在JAVA虛擬機器規範裡面只規定了一個指向對象的引用,並沒有定義這個引用該通過哪種方式去定位,以及訪問到JAVA堆中的對象的具體位置,因此不同虛擬機器實現的對象訪問方式會有所不同,主流的訪問方式有兩種:控制代碼和直接指標。
JAVA堆中將會劃分出來一塊記憶體作為控制代碼池,reference中就是儲存了對象的控制代碼地址,而控制代碼中包含了對象執行個體資料和類型資料各自的具體地址資訊。
使用控制代碼訪問的最大好處是reference中儲存的是穩定的控制代碼地址,在對象被移動時,只會改變控制代碼中的執行個體資料指標,而reference本身不需要被修改。
相比較控制代碼的訪問方式,JAVA堆中不會單獨劃分記憶體,reference中直接儲存了對象地址,而對象中包含了物件類型資料的地址資訊。
使用直接指標的最大好處就是速度更快,節省了一次指標定位需要的時間開銷,由於JAVA對象訪問十分頻繁,這類開銷積小成多後也是一項非常可觀的執行成本。Sun HotSpot虛擬機器使用的就是這種訪問方式。
一個實體類,名為Stu:
[html] view plain copy print?
- public class Stu extends Object{
- private String name;
- private int age;
- public Stu(String name,String age){
- this.name = name;
- this.age = age;
- }
- public String getName(){
- return this.name;
- }
- ...
- }
建立Stu對象:
Stu kevin = new Stu(“kevin”,15);
這樣根據上文解釋如下:
kevin作為一個reference類型的變數儲存在本地變數表中,在hot spot虛擬機器中,儲存的是(kevin=)具體對象的直接地址;new Stu(“kevin”,15)就是執行個體化了一個對象,JAVA堆中Stu實體類的所有的欄位資訊,比如name=”kevin”,age=15。此時,JAVA堆中還儲存了Stu對象的類型資料的地址資訊,通過這個地址在方法區中可以尋找對象的類型、父類、實現的介面、方法等資訊。
【2】JVM-JAVA對象的訪問