這篇文章將簡單的說明下當(dāng)我們運(yùn)行java程序時jvm(java虛擬機(jī))的內(nèi)存分配情況。
首先我們先來感觀的認(rèn)識下幾個名詞:
1、棧,一般來說,基本數(shù)據(jù)類型直接在棧中分配空間,局部變量(在方法代碼段中定義的變量)也在棧中直接分配空間,當(dāng)局部變量所在方法執(zhí)行完成之后該空間便立刻被jvm回收,還有一種是引用數(shù)據(jù)類型,即我們通常所說的需要用關(guān)鍵字new創(chuàng)建出來的對象所對應(yīng)的引用也是在棧空間中,此時,jvm在棧空間中給對象引用分配了一個地址空間(相當(dāng)于一個門牌號,通過這個門牌號就可以找到你家),在堆空間中給該引用的對象分配一個空間,棧空間中的地址引用指向了堆空間中的對象區(qū)(通過門牌號找住址);
2、堆,一般用來存放用關(guān)鍵字new出來的數(shù)據(jù)。
接下來我們再通過一段程序來直觀感受下程序運(yùn)行時jvm的內(nèi)存情況,
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
package demo; public class student { private string name; private int age; public void study() { system.out.println( "i love study!" ); } public string getname() { return name; } public void setname(string name) { this .name = name; } public int getage() { return age; } public void setage( int age) { this .age = age; } } |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
package demo; public class studentdemo { public static void main(string[] args) { student student = new student(); system.out.println(student.getname() + ":" + student.getage()); student.setname( "john" ); student.setage( 23 ); system.out.println(student.getname() + ":" + student.getage()); student.study(); student student2 = student; student2.setname( "jack" ); student2.setage( 25 ); system.out.println(student2.getname() + ":" + student2.getage()); system.out.println(student.getname() + ":" + student.getage()); } } |
當(dāng)我們運(yùn)行程序時,jvm會把student類與studentdemo類編譯完然后加載到j(luò)vm中一個叫方法區(qū)的地方,類的成員變量與成員方法也被加載到方法區(qū)中,此時內(nèi)存模型如下
可以看到study方法右邊各有一個16進(jìn)制的標(biāo)記,而name與age變量沒有,這是因?yàn)槊總€對象都有各自的成員變量,而類中的成員方法卻可以被每個對象所共用,為了節(jié)省內(nèi)存空間,jvm為方法分配了該標(biāo)記(也叫內(nèi)存地址)便于每個new出來的對象查找調(diào)用,接著jvm會自動尋找main方法,在棧中為main方法申請一個空間,這個過程也叫入棧,然后執(zhí)行我們student類中第5行代碼,這時候,jvm在堆空間中分配一塊內(nèi)存給student對象,并為其分配一個內(nèi)存地址(如果對象的成員變量沒有賦值,則jvm會為變量賦初始值),在棧中分配一塊內(nèi)存空間用于指向堆空間中的student對象區(qū)的內(nèi)存地址,此時內(nèi)存模型如下
接著看代碼第8行與第9行,程序?yàn)閟tudent對象的成員變量賦值,jvm會根據(jù)student所指向的地址在堆內(nèi)存中尋找student類的變量,并為變量賦新的值
第12行,這時student對象調(diào)用study方法,jvm在棧空間中為study方法申請了一塊內(nèi)存空間
study方法執(zhí)行完后,立即釋放棧空間,代碼第14行,student2對象的引用指向了student所指向的地址
代碼15與16行,為student2的變量賦值,由于student2與student指向了同一個地方,所以這時student對象中變量的值也被改變
到這,main方法中所有代碼執(zhí)行完畢,main方法所占用的棧空間也被回收,而堆空間等待gc回收
代碼執(zhí)行結(jié)果如下:
1
2
3
4
5
|
null : 0 john: 23 i love study! jack: 25 jack: 25 |
感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!
原文鏈接:http://blog.csdn.net/lin353809836/article/details/69367482