JVM中堆和棧的區別


Java程序為了提高程序的效率,就對數據進行了不同空間的分配,具體如下:

1.棧:存放的是局部變量;

2.堆:存放的是所有new出來的東西;

3.方法區:(面向對象的東西)

4.本地方法區:存放的是和系統相關的東西,比如Windows、Linux。

5.寄存器:CPU使用的。

 

以下着重介紹堆和棧!

棧(stack)和堆(heap)都是JAVA在RAM中存放數據的地方。

*與C++不同,JAVA自動管理棧和堆,程序員不能直接的設置棧和堆。

棧內存:

  存儲的都是局部變量,而且變量所屬的作用域一旦結束,該變量就自動釋放。

堆內存:

  存儲的是數組和對象(其實數組也是對象),凡是new建立在堆中。

  特點:1.每一個實體都有首地址值;

     2.堆內存中的每一個變量都有默認初始化值,根據類型的不同而不同;

棧和堆在內存中的存儲方式可參考下圖:

舉例:int[] arr = new int[3];

步驟:

  1,創建變量arr,且這個局部變量在主函數中,故主函數的代碼段先進棧;

  2,右邊用new建立的對象是實體,故放在堆中;

  3,給該對象分配一個內存地址,用來存放該對象,比如:0x0045;(堆會對其中的對象進行默認初始化)

  4,將對象的地址0x0045賦給棧中的變量arr,而arr就指向堆中的這個地址(也可以作稱作引用這個地址),類似於c++中的指針。

棧的優勢:存取速度比堆要快,僅次於直接位於CPU中的寄存器。

棧的缺點:1.存在棧中的數據大小和生存期必須是確定的,缺乏靈活性。

     2.棧數據在多個線程或者多個棧之間是不可以共享的。(但是,在棧內部多個值相等的變量是可以指向一個地址的)

堆的優勢:可以動態的分配內存大小,生存期也不必事先告訴編譯器,JAVA的垃圾收集器會自動收走不用的數據。

堆的缺點:由於要在運行時動態分配內存,存取速度較慢。

 

JAVA中的數據類型有兩種:

  一.基本類型(byte,short,int,long,float,double,boolean,char)

這種類型定義的變量被稱作自動變量,自動變量存的是字面值,不是類的實例(即不是類的引用)。

比如:int a=3,long b=255L   這些字面值的數據,由於大小可知,生存期可知,出於追求速度的原因,就存在於棧中。

  二.包裝類數據(如Integer,String,Double等將相應的基本數據類型包裝起來的類,這些類數據全部存在於堆中)

JAVA用new語句來顯式的告訴編譯器,在運行時才根據需要動態創建,因此比較靈活,但缺點是要占用更多的時間。

注意:包裝類的值不可修改!

 

--------------------------------------------------------------------------------------------------------------------------------------------

 

由上圖1可知,JVM的基本結構包括:類裝載器,內存區域,執行引擎,本地庫接口。

下面主要介紹一下內存區:

1.虛擬機棧

  每當啟動一個新線程的時候,java虛擬機都會為它分配一個java棧,故每個線程包含一個棧區。

每個棧中的數據都是私有的,其它棧不能訪問。棧分為3個部分:基本類型變量區、執行環境上下文、操作指令區。

2.堆內存

  存儲的全部是對象,每個對象包含一個與之對應的class信息-----class的目的是得到操作指令。

jvm只有一個堆區被所有線程共享,堆區中不存放基本類型和對象引用,只存放對象本身。

3.方法區

  在方法區中,存儲了每個類的信息(包括類的名稱、方法、字段)、靜態變量、常量以及編譯器編譯后的代碼等。

4.本地方法棧

  和虛擬機棧的作用差不多,只不過是為JVM使用到的native方法服務的。

*.在HotSopt虛擬機中直接就把本地方法棧和虛擬機棧合二為一了。

5.程序計數器

  用於保存當前線程執行的內存地址。

由於JVM程序是多線程執行的,為了保證線程切換回來后,還能恢復到原先狀態,就需要一個獨立的計數器,記錄之前中斷的地方,可見程序計數器也是線程私有的。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM