之前寫過一篇隨筆
https://www.cnblogs.com/qianjinyan/p/10352749.html
現在看看,貌似不是很准確,方法區和棧應當區分開來,兩者有很大的區別
看下面的一個對象,如何進行引用,引用變量如何存儲,對象信息又存儲在哪兒
class Person{
private int id;
private String name;
@Override
public String toString() {
return "Person{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}
@Test
public void test2019() {
Person person = new Person();
person.name="Zhangsan";
person.id=30;
System.out.println(person);
}
一般來說,一個Java的引用訪問涉及到3個內存區域:JVM棧,堆,方法區。
以最簡單的本地變量引用: Person person = new Person()為例:
Person person 表示一個本地引用,存儲在JVM棧的本地變量表中,表示一個reference類型數據;
new Person()作為實例對象數據存儲在堆中;
堆中還記錄了Object類的類型信息(接口、方法、field、對象類型等)的地址,這些地址所執行的數據存儲在方法區中;
在Java虛擬機規范中,對於通過reference類型引用訪問具體對象的方式並未做規定,目前主流的實現方式主要有兩種:
1,通過句柄訪問(圖來自於《深入理解Java虛擬機:JVM高級特效與最佳實現》):
通過句柄訪問的實現方式中,JVM堆中會專門有一塊區域用來作為句柄池,存儲相關句柄所執行的實例數據地址(包括在堆中地址和在方法區中的地址)。這種實現方法由於用句柄表示地址,因此十分穩定。
2,通過直接指針訪問:(圖來自於《深入理解Java虛擬機:JVM高級特效與最佳實現》)
通過直接指針訪問的方式中,reference中存儲的就是對象在堆中的實際地址,在堆中存儲的對象信息中包含了在方法區中的相應類型數據。這種方法最大的優勢是速度快,在HotSpot虛擬機中用的就是這種方式。