閱讀大牛們的文章,我一個小菜鳥進行了系統的小結,如有內容重複請見諒,謝謝!
首先理解堆(heap)、棧(stack)和方法區(method)也叫靜態存儲區的概念,然後比較它們之間的特點
堆:
存儲的全部是對象,每個對象都包含一個與之對應的class文件信息,class的目的是得到操作指令。
在Java中一切都是對象,而對象又是類的實例,都是通過new()來新建對象的,有些類運用了單例模式來返回類的實例,
只不過這個實例是在該類內部通過new()來創建的,把它隱藏了而已。
棧:
1.棧中只保存基本數據類型的對象和自定義對象的引用(不是對象),對象都存放在堆區中。
2.每個棧中的數據(原始類型和對象引用)都是私有的,其它棧不能訪問。
3.棧分爲3個部分:基本類型變量區,執行環境上下文,操作指令區。
方法區:
1.方法區也可以稱作靜態區,方法區包含所有的class和static變量。
2.方法區包含的都是在整個程序中永遠唯一的元素。
關於線程是否共享:
棧:每個線程包含一個棧區
堆:JVM(Java Virtual Machine)中只有一個堆區被所有線程共享
方法區:被所有線程共享
關於棧與堆的執行順序:
棧:先進後出(通常說爲壓棧) 舉個例子:就像小時候玩的氣槍彈匣裝子彈一樣,先進去的子彈最後才被打出來。
堆:先進先出
關於棧與堆緩存方式的區別(生命週期):
棧使用的是一級緩存,他們通常都是被調用時處於存儲空間中,調用完畢後立即釋放。
堆是存放在二級緩存中,生命週期由JVM的垃圾回收算法來決定,調用這些對象的速度效率相對低一點。
關於數據共享的形式:
基本類型和基本數據類型的包裝類:
基本類型有:byte、short、char、int、long、boolean。
基本類型的包裝類:Byte、Short、Character、Integer、Long、Boolean。
基本類型存儲在棧中,而基本類型包裝類存儲在堆中。
棧中有一個很重要的特性:棧中的數據可以共享。
而堆中的數據不可以共享。
關於棧和堆的功能與作用:
堆主要用來存放對象的,棧主要用來執行程序的。
每一個Java應用都唯一對應一個JVM實例,每一個實例唯一對應一個堆。Java中分配堆內存是自動初始化的,java中
所有對象的存儲空間都是在堆中分配的,但是這個對象的引用確是在堆棧中分配。
對於一個java程序來說,它的運行就是通過對堆棧的操作來完成的,堆棧以幀爲單位保存線程的狀態。
java中對堆棧只進行兩種操作:以幀爲單位的壓棧和出棧操作。
關於Java變量在內存中的分配:
1.類變量也可以叫做static修飾的變量:
在程序加載時系統就爲它在堆中開闢了內存,堆中的內存地址存放於棧,以便快速訪問,靜態變量的生命週期一致持續到整個系統關閉。
2.實例變量:
當使用java關鍵字new的時候,系統在堆中開闢一塊空間分配給變量,實例變量的生命週期--當實例變量的引用丟失後,將被垃圾回收機制(GC)列入可回收名單,但並不是馬上就釋放堆中內存。
3.局部變量:
局部變量由聲明在某方法或某代碼段裏(example: for循環)執行到它的時候在棧中開闢內存,當局部變量一旦脫離作用域(即}結束後),內存立即釋放。