1. 程式人生 > >【2】JVM-JAVA對象的訪問

【2】JVM-JAVA對象的訪問

lin oar XML nts java棧 article value new 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?
  1. public class Stu extends Object{
  2. private String name;
  3. private int age;
  4. public Stu(String name,String age){
  5. this.name = name;
  6. this.age = age;
  7. }
  8. public String getName(){
  9. return this.name;
  10. }
  11. ...
  12. }

創建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對象的訪問