Java 堆、棧、方法區的區別

結構化語言裏函數(子程序)調用最方便的實現方式就是用棧,以至於現在絕大部分芯片都對棧提供芯片級的硬件支持,一條指令即可搞定棧的pop操作。棧的好處是:方便、快、有效避免內存碎片化。棧的問題是:不利於管理大內存(尤其在16位和32位時代)、數據的生命週期難於控制(棧內的有效數據通常是連續存儲的,所以pop時後申請的內存必須早於先申請的內存失效),所以棧不利於動態地管理並且有效地利用寶貴的內存資源。於是我們有了堆。

JAVA的JVM的內存可分爲3個區堆(heap)棧(stack)方法區(method)也叫靜態存儲區

堆區:

1.堆內存用來存放由new創建的對象和數組,存儲的全部是對象,每個對象都包含一個與之對應的class的信息。(class的目的是得到操作指令) 

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

3、優缺點

優:堆是由垃圾回收來負責的,堆的優勢是可以動態地分配內存大小,生存期也不必事先告訴編譯器,因爲它是在運行時動態分配內存的,Java的垃圾收集器會自動收走這些不再使用的數據。

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

棧區:

1.每個線程包含一個棧區,棧中只保存基礎數據類型的對象和自定義對象的引用(不是對象),對象都存放在堆區中 

函數中定義的一些基本類型的變量數據和對象的引用變量都在函數的棧內存中分配。

2.每個棧中的數據(原始類型和對象引用)都是私有的,其他棧不能訪問。 

3.棧分爲3個部分:基本類型變量區、執行環境上下文、操作指令區(存放操作指令)。

4、優缺點

棧的優勢:存取速度比堆要快,僅次於寄存器,棧數據可以共享(指的是線程共享,而給進程共享)。

缺點:存在棧中的數據大小與生存期必須是確定的,缺乏靈活性。棧中主要存放一些基本類型的變量數據(int, short, long, byte, float, double, boolean, char)和對象句柄(引用)。

方法區:

1.又叫靜態區,跟堆一樣,被所有的線程共享。方法區包含所有的class和static變量,用於存儲虛擬機加載的類信息、常量、靜態變量、即時編譯器編譯後的代碼等數據。 

2.方法區中包含的都是在整個程序中永遠唯一的元素,如class,static變量。

常量池(constant pool)

   常量池指的是在編譯期被確定,並被保存在已編譯的.class文件中的一些數據。除了包含代碼中所定義的各種基本類型(如int、long等等)和對象型(如String及數組)的常量值(final)還包含一些以文本形式出現的符號引用

比如:類和接口的全限定名; 字段的名稱和描述符; 方法和名稱和描述符。虛擬機必須爲每個被裝載的類型維護一個常量池。常量池就是該類型所用到常量的一個有序集和,包括直接常量(string,integer和floating point常量)和對其他類型,字段和方法的符號引用。對於String常量,它的值是在常量池中的。而JVM中的常量池在內存當中是以表的形式存在的,對於String類型,有一張固定長度的CONSTANT_String_info表用來存儲文字字符串值,注意:該表只存儲文字字符串值,不存儲符號引用。說到這裏,對常量池中的字符串值的存儲位置應該有一個比較明瞭的理解了。在程序執行的時候,常量池會儲存在方法區(Method Area),而不是堆中。




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章