1. 程式人生 > >JAVA基礎知識|堆和棧

JAVA基礎知識|堆和棧

http @override 堆和棧 才會 圖形 根據 this 定義 執行

一、java六個存儲數據的地方

1)寄存器(register):這是最快的存儲區,因為它位於不同於其他存儲區的地方——處理器內部。但是寄存器的數量極其有限,所以寄存器由編譯器根據需求進行分配。你不能直接控制,也不能在程序中感覺到寄存器存在的任何跡象。

2)棧(stack):位於通用RAM中,這是一種快速有效的分配存儲方法,僅次於寄存器。用於存放基本數據類型的變量和對象、數組的引用。

3)堆(heap):也位於通用RAM中,用於存放new出來的對象,用堆進行存儲比用棧進行存儲需要更多的時間。

4)靜態存儲(static storage):這裏的“靜態”是指“在固定的位置”。靜態存儲裏存放程序運行時一直存在的數據,即關鍵字static標識的屬性,但JAVA對象不會存放在靜態存儲空間裏。

*為什麽非靜態方法,不可以使用靜態屬性?

因為靜態方法和靜態屬性的編譯要在非靜態方法之後,當非靜態方法編譯使用的時候,靜態屬性還沒生成,會導致報錯!

5)常量存儲(constant storage):常量值通常直接存放在程序代碼內部,這樣做是安全的,因為它們永遠不會被改變。有時在嵌入式系統中,常量本身會和其他部分分割離開,所以在這種情況下,可以選擇將其放在ROM中。所以常量存儲用於存放final關鍵字修飾的字符串常量和基本類型常量。

6)非RAM存儲:如果數據完全存活於程序之外,那麽它可以不受程序的任何控制,在程序沒有運行時也可以存在。

二、堆和棧

相同點:都用於存儲數據

不同點:  

  1)棧用於存放基本數據類型的變量和對象、數組的引用,堆用於存放new出來的對象

  2)棧中存放的數據,大小和生存期必須確定,靈活性不足。堆中存放的數據,不必知道數據大小,也不必知道生命周期,靈活性較高,導致速度較慢

  3)生命周期

     當一個方法執行時,每個方法都會建立自己的內存棧,在這個方法中定義的變量將會放到這塊棧內存裏,隨著方法的結束而銷毀(不需要使用GC)。

     當執行new對象的時候,數據才會在堆中生成,只有當一個對象沒有任何引用變量去引用它時,系統的垃圾回收器(GC)才會在合適的時候回收它。

  4)棧解決程序的運行問題,即程序如何執行,或者說如何處理數據;堆解決的是數據存儲的問題,即數據怎麽放、放在哪兒。

技術分享圖片
/**
 * 汽車類
 */
public
class Car { //編號 private int id; //車名 private String name; //車速 private double speed; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public double getSpeed() { return speed; } public void setSpeed(double speed) { this.speed = speed; } public Car(int id, String name, double speed) { this.id = id; this.name = name; this.speed = speed; } public Car() { } @Override public String toString() { return "Car{" + "id=" + id + ", name=‘" + name + ‘\‘‘ + ", speed=" + speed + ‘}‘; } }
View Code 技術分享圖片
        int i = 1;
        Car car = new Car(1, "bmw", 200);
View Code

圖形化分析:

技術分享圖片

繼續看下面代碼,並思考輸出值

技術分享圖片
        int i = 1;
        Car car = new Car(1, "bmw", 200);
        Car newCar = car;
        newCar.setSpeed(300);
        System.out.println(car.toString());
        System.out.println(newCar.toString());
View Code

圖形化分析:

技術分享圖片

代碼中Car newCar = car;只是將引用的地址給了newCar,他們指向堆中同一個對象,所以當newCar對對象做出改變的時候,car所指向的對象也同樣發生了變化。

有時候在代碼中,我們不希望兩個變量指向同一個對象,可以使用clone的方式,重新在堆中生成一個相同的對象。

JAVA基礎知識|堆和棧