JVM內(nèi)存中的堆和棧的區(qū)別

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容