2011-07-23 77 views
30
  • Java內存空間(Perm Space,Space Stack,堆空間)有什麼區別?
  • JVM何時使用這個或另一個?
  • 如果我使用Scala/Groovy /等,有區別嗎?
+3

相關:http://stackoverflow.com/questions/4848669/perm-space-vs-heap-space ,http://stackoverflow.com/questions/1279449/what-is-perm-space – Mat

+1

[該堆棧是一個實現細節](http://blogs.msdn.com/b/ericlippert/archive/2009/04/ 27 /在堆疊-是-AN-實施-detail.aspx)。對於Java來說可能並不重要,因爲它缺少用戶定義的值類型,但對於使用垃圾回收語言工作的每個人來說,仍然是重要的讀取。 – delnan

+0

其他JVM語言使用相同的標準? – caarlos0

回答

71

只需

  • 堆空間:所有活動對象都在這裏進行分配。
  • 堆棧空間:在方法調用或變量實例化中存儲對變量對象的引用。
  • 彼爾姆空間:存儲加載的類信息

例如:

Student std = new Student(); 

執行上述存儲器狀態的行之後會是這樣。

  • 堆:賣場 「新學生()」
  • 堆棧:關於 「性病」
  • 彼爾姆空間用於存儲信息:存儲有關Student類
+12

堆棧也存儲原始文字。 –

+0

@Daniel:謝謝你的信息。我不知道,我會更多地研究它。 – Kowser

+0

@Daniel:Stack也存儲原始文字。你那是什麼意思?嚴格地說,Stack不存儲_anything_堆棧中只有方法調用的參數和用於評估表達式的「值」。 –

2

原諒我加入一個答案這樣一個古老的問題 - 當前的答案很好,但由於靜態代碼和Java 8更新,遺漏了一些邊緣案例。

概述

  • 棧每線程
    • 分配
    • 存儲本地引用和原語
    • 這是區域性存儲器 - 當一個方法或線頭,所有的數據堆棧丟失
    • 訪問速度最快,所以本地原語比你更快本身不是本地對象
    • 所有分配的對象實例存在這裏
    • 分爲三代,與年輕一代成爲首位GC看起來
    • 提供給所有線程,以便分配並且應該同步取消分配
    • 該內存可能會變成碎片(,但您通常不會自己管理它)
  • PermGen的
    • 商店加載的類信息
    • 存儲不可改變的信息(Primatives,實習字符串)
    • 商店靜態類members

示例代碼

public class SimpleVal { //The Class (loaded by a classloader) is in the PermGen 

    private static final int MAGIC_CONSTANT = 42; //Static fields are stored in PermGen 
    private static final SimpleVal INSTANCE = new SimpleVal(1); //Static field objects are created in the heap normally, with the reference in the PermGen ('class statics' moved to the heap from Java 7+) 
    private static SimpleVal previousInstance; //Mutable static fields also have their reference in PermGen so they can easily cause memory leaks 

    private int value; //Member variables will be part of the heap 

    public SimpleVal(int realValue) { 
     value = realValue; 
     ... 
    } 

    public static int subtract(SimpleVal val1, SimpleVal val2) { 
     .... 
    } 

    public int add(SimpleVal other) { //Only one copy of any method (static or not) exists - in PermGen 
     int sum = value + other.value; //Local values in methods are placed in the Stack memory 
     return sum; 
    } 

} 

public static void main(String[] args) { 

    SimpleVal val1 = null; 
    SimpleVal val2 = new SimpleVal(3); //Both of these variables (references) are stored in the Stack 

    val1 = new SimpleVal(14); //The actual objects we create and add to the variables are placed in the Heap (app global memory, initially in the Young Gen space and later moved to old generation, unless they are very large they can immediately go old gen) 

    int prim = val1.add(val2); //primitive value is stored directly in the Stack memory 
    Integer boxed = new Integer(prim); //but the boxed object will be in the heap (with a reference (variable) in the Stack) 

    String message = "The output is: "; //In Java 7+ the string is created in the heap, in 6 and below it is created in the PermGen 
    System.out.println(message + prim); 

} 

的Java 8注: PermGen的空間與所謂元空間所取代。這個功能仍然相同,但可以自動調整大小 - 默認情況下,Metaspace auto會將其本地內存大小增大到最大值(在JVM params中指定),但PermGen始終具有與堆內存連續的固定最大大小。

Android Note:從Android 4.0開始(從實踐3.0開始)Android應該遵守所述的內存合同 - 但在舊版本中爲implementation was broken。 Android-Davlik中的'Stack'內存實際上是基於寄存器的(指令大小和計數在兩者之間有所不同,但對於開發者來說,功能保持不變)。

最後,以獲得更多信息我曾經觀察到在StackOverflow上這個問題的最佳答案是here