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)存空間