1. 程式人生 > >Java堆和棧分配原理簡析以及靜態和非靜態關係簡述

Java堆和棧分配原理簡析以及靜態和非靜態關係簡述

1.:函式中定義的基本型別變數以及物件的引用變數都是存在於棧中,當定義了一個變數後,就會在棧中為其分配記憶體空間,當這個變數的作用域結束後,就會釋放此變數的記憶體空間,以便另作他用。棧的優勢是,存取速度比堆要快,僅次於直接位於CPU中的暫存器。但存在棧中的資料大小與生存期必須是確定的,缺乏靈活性。另外,棧資料可以共享注意:棧中的共享與堆中的共享是不同的,在棧中,例如 int a = 3; int b = 3; a = 4; 在這裡首先對 a 進行判斷,如果棧中沒有 3 ,則會把 3 存進來,並將 a 指向 3 ,當建立 b 的引用變數後發現棧中已經有了 3 ,所以直接 b 指向 3,此即為棧中的共享,當 a改變指向後,並不會影響 b ,節省空間

。但是,在堆中,當建立了兩個物件,一個物件改變其所指向的內部成員後,會對另一個物件產生影響,即通過另一個物件再次訪問時會得到第一個物件改變後的結果。 2.:簡單來說,所有 new 的都存在於堆中。Java用new()語句來顯式地告訴編譯器,在執行時才根據需要動態建立,雖然比較靈活,但缺點是要佔用更多的時間。堆的優勢是可以動態地分配記憶體大小,生存期也不必事先告訴編譯器,Java的垃圾收集器會自動收走這些不再使用的資料。但缺點是,由於要在執行時動態分配記憶體,存取速度較慢。另外:包裝類也是存在於堆中。 靜態中不能訪問非靜態的原因: 程式最終都是在記憶體中執行,變數只有在記憶體中佔有一席之地時才會被訪問,類的靜態成員(變態和方法)屬於類本身,在類載入的時候就會分配記憶體,可以 通過類名直接去訪問,非靜態成員(變數和方法)屬於類的物件,所以只有在類的物件存在(建立例項)的時候才會分配記憶體,然後通過類的物件去訪問。 在一個類的靜態成員中去訪問非靜態成員之所以會出錯是因為在類的非靜態成員不存在的時候靜態成員就已經存在了,訪問一個記憶體中不存在的東西當然會出錯。 類在需要呼叫的時候被載入。