您好,登錄后才能下訂單哦!
JVM的內存分配方式是什么?這個問題可能是我們日常學習或工作經常見到的。希望通過這個問題能讓你收獲頗深。下面是小編給大家帶來的參考內容,讓我們一起來看看吧!
java虛擬機編譯時的內存存儲有三類:
1、靜態(方法區)存儲
2、棧式存儲
3、堆式存儲
靜態存儲是指在編譯的時候就得確定這個數據的存儲需求,然后給它分配固定的內存,所以說靜態存儲不允許有可變的數據結構出現,因為可變的數據不會確定存儲空間
棧式存儲相比于靜態存儲正好相反,在編譯時,棧式存儲指定的存儲數據是不確定的,只有真正運行到這個數據的時候才知道,那時候才能為它分配內存空間
堆式存儲相對于棧式存儲,棧式存儲在分配空間前必須指定數據要分配多少內存,而堆式存儲則完全無法確定數據結構需要的內存空間,比如可變數組,對象實例,所以堆是由大片的可利用塊和空閑塊組成
靜態存儲相對簡單,所以我們著重分析棧和堆的關系和區別
區別:
在棧中的數據一旦超過它的作用域之后,就會被釋放,內存會被其他數據占用
在堆中,分配的內存是由java虛擬機自動垃圾回收器管理,這些可變數組、對象在沒有引用變量指向他們的時候,才會變成垃圾,但仍然占著內存,之后再一個不確定的時間被垃圾回收器釋放掉
在一個JVM實例中,堆區只有一個,而棧可以有多個
關系
在堆中創建一個數據之后,可以在棧中定義一個變量,這個變量指向堆中的某個數據(指向數據的首地址),也就是說這個變量變成了堆中數據的引用變量,可以利用引用變量來訪問堆中的數據,這就是java的指針。
并且每個java應有都會有一個JVM實例,每個實例對應一個堆,在這個應有運行期間,所有的類實例和數組都放在這個堆中,在建立一個對象的時候會從兩個地方分配內存,在堆中是這個對象的實際值,而在棧(堆棧,也叫stack)中,分配的是堆中這個對象的索引
先看下這張圖(嗯 畫的很形象)
JVM是基于堆棧的,每新建一個線程會分配一個堆棧,它是以幀為單位,有先進后出的特性(看圖可懂)
當激活一個java方法時,就為往堆棧中放入一個幀(這就是壓棧),在這個方法的執行過程中,這個幀就會用來保存數據
方法的存在有堆棧決定,而由于先進后出的形式,方法之間嵌套的越深,stack的內存就越難釋放,所以遞歸這樣的方法本人不推薦使用
下面貼出壓棧和出棧的具體實現
使用壓棧出棧來將字符串倒序
String value = "test 1234567890"; StringBuffer result = new StringBuffer(); Stack stack = new Stack(); for(char c : value.toCharArray()) { stack.push(c); } while (!stack.empty()) { result.append(stack.pop()); } value = result.toString();
感謝各位的閱讀!看完上述內容,你們對JVM的內存分配方式是什么大概了解了嗎?希望文章內容對大家有所幫助。如果想了解更多相關文章內容,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。