1侧纯、棧(stack)是存放方法的局部變量的內(nèi)存空間棘钞,每個方法都會分配一塊內(nèi)存空間frame鹏秋,方法一旦執(zhí)行完成,frame就被銷毀滤否,對于原始類型,變量的值也保存在stack中最仑,對于引用類型藐俺,stack里保存的是指向?qū)ο蟮膬?nèi)存地址(引用)
</br>
2、堆(heap)是存放的Object泥彤,java是傳值的欲芹,不是傳引用的。
</br>
3吟吝、垃圾回收器GC(Garbage Collection):
局部變量方法在執(zhí)行完后內(nèi)存馬上被回收耀石。
Heap里面的對象由GC自動回收。
GC維護(hù)和檢測對象的引用爸黄,當(dāng)引用數(shù)為0時自動回收滞伟。
GC并不是實時回收的。
</br>
以下面的程序為例來說明jvm內(nèi)存中的Stack炕贵,Heap和GC(垃圾回收):
public class MakeMoney {
public static void main(String [] args){
double rate = 30;
double money = 0.0;
Person zhangsan = new Person("張三",50);
money = task1(rate);
money = money+task2(zhangsan);
System.out.println("張三一共賺了" + money +"元");
}
public static double task1(double rate){
int hour = 5;
return rate*hour;
}
public static double task2(Person person){
int hour = 6;
return hour*person.rate;
}
}
class Person{
private String name;
public double rate;
public Person(String name,double rate){
this.name = name;
this.rate = rate;
}
}
第一步:在程序未執(zhí)行時的堆棧如下圖
第二步:開始執(zhí)行main()方法梆奈,首先jvm會先為main方法分配一段內(nèi)存空間,內(nèi)存又依次為rate称开,money亩钟,zhangsan開辟空間,因為zhangsan是引用數(shù)據(jù)類型鳖轰,所以jvm會在Heap中創(chuàng)建對象清酥,分配一段內(nèi)存空間,Stack中的zhangsan指向Heap中為zhangsan這個對象的內(nèi)存地址
第三步:接著執(zhí)行task1蕴侣,jvm為task1方法分配內(nèi)存空間焰轻,task1中有兩個變量rate和hour,jvm會從main的內(nèi)存中將rate的的值傳遞過來昆雀,同時為hour分配空間辱志,如下圖
第四步:task1執(zhí)行完蝠筑,jvm會自動釋放內(nèi)存,task1的內(nèi)存塊將不存在
接下來將執(zhí)行task2揩懒,傳遞一個person進(jìn)來什乙,jvm會給person和hour分配內(nèi)存空間,person同樣指向heap中的內(nèi)存空間已球,它是main方法中zhangsan的引用
最后臣镣,task2執(zhí)行完后,jvm自動回收task2的內(nèi)存空間智亮,接著回收main函數(shù)的內(nèi)存空間退疫,然后沒有任何對象指向Heap中的zhangsan,jvm就會回收Heap中的zhangsan對象的內(nèi)存空間