【內存分析】內存分析(未完成)
棧的特點如下:
1. 棧描述的是方法執行的內存模型。每個方法被調用都會創建一個棧幀(存儲局部變量、操作數、方法出口等)
2. JVM為每個線程創建一個棧,用於存放該線程執行方法的信息(實際參數、局部變量等)
3. 棧屬於線程私有,不能實現線程間的共享!
4. 棧的存儲特性是“先進後出,後進先出”
5. 棧是由系統自動分配,速度快!棧是一個連續的內存空間!
堆的特點如下:
1. 堆用於存儲創建好的對象和數組(數組也是對象)
2. JVM只有一個堆,被所有線程共享
3. 堆是一個不連續的內存空間,分配靈活,速度慢!
方法區(又叫靜態區)特點如下:
1. JVM只有一個方法區,被所有線程共享!
2. 方法區實際也是堆,只是用於存儲類、常量相關的信息!
3. 用來存放程序中永遠是不變或唯一的內容。(類信息【Class對象】、靜態變量、字符串常量等)
來源:速學堂 4.4 面向對象的內存分析
了解棧、堆和方法區的特點後,我們來對以下代碼進行內存分析
public class Student { //屬性(成員變量) field s int id; String name; int age; Computer comp; //方法 void study(){ System.out.println("我在學習"); } void play() { System.out.println("我在玩碧藍航線!用筆記本"+comp.brand); } Student (){ //構造方法。用於創建這個類的對象,無參的構造方法可以由系統自動生成 } public static void main(String[] args) { Student stu = new Student();//通過Student類的構造函數Student()方法新建一個stu對象 stu.age=19; stu.id=19; stu.name="水音"; Computer c1 = new Computer(); c1.brand = "神舟"; stu.comp = c1; stu.play(); stu.study(); } } class Computer{ String brand; }
讓我們回到萬物的起點
javac Student.java 和 java Student
javac 是將 .java 文件編譯成 JVM(java虛擬機)能夠讀懂的 .class java字節碼文件
java 則是執行字節碼文件,我們從這裏開始分析
在調用 java 的時候,啟動虛擬機,內存空間如下圖所示
接著是執行 Student 類,執行這個類之前需要找到這個類,首先需要把 Student 類加載到內存空間裏面
接著在方法區裏面,就有了這個類的信息
有了這些信息後,相當於 java Student 這條命令執行完了
接著就開始尋找 main 方法,main 方法是程序執行的入口
在調用 main 方法的時候就會在棧中開辟一個棧幀
main 方法
public static void main(String[] args) { Student stu = new Student();//通過Student類的構造函數Student()方法新建一個stu對象 stu.age=19; stu.id=19; stu.name="水音"; Computer c1 = new Computer(); c1.brand = "神舟"; stu.comp = c1; stu.play(); stu.study(); }
main 方法首先定義了一個 Student 類型的引用變量 stu ,目前它的值為空(null)
接著 new 了一個對象,根據 Student 類的構造器(構造方法),所以在棧中開辟一個新的棧幀
開辟完後開始執行這個方法,依據構造器初始化這個類,生成這個類的對象
執行完後獲得對象 ,棧幀彈出
接著將這個新建好的對象給 stu
也就是把 stu 的地址指向新建好的對象的地址
通過地址值將它們關聯起來
Tip:不用在意 1e6d1014 這個地址是怎麽來的,只是隨便打的
接著執行 stu.age
public static void main(String[] args) { Student stu = new Student();//通過Student類的構造函數Student()方法新建一個stu對象 stu.age=19; stu.id=19; stu.name="水音"; Computer c1 = new Computer(); c1.brand = "神舟"; stu.comp = c1; stu.play(); stu.study(); }
在 mian 方法裏執行,所以在 main 方法的棧幀裏面找 stu 對象,根據 stu 的地址找到 age
並將 age 賦值為 19
id 的賦值同上
需要註意的是 name 的賦值
找到 name 以後,會在方法區裏找到 水音 這個字符串常量並將 name 的地址指向它
【內存分析】內存分析(未完成)