摘要:前言本篇講解在程序運行時,內存的分配是怎樣進行的虛擬機編譯時的內存存儲有三類靜態(tài)方法區(qū)存儲棧式存儲堆式存儲靜態(tài)存儲是指在編譯的時候就得確定這個數(shù)據(jù)的存儲需求,然后給它分配固定的內存,所以說靜態(tài)存儲不允許有可變的數(shù)據(jù)結構出現(xiàn),因為可變的數(shù)據(jù)不
前言
本篇講解在java程序運行時,內存的分配是怎樣進行的?
java虛擬機編譯時的內存存儲有三類:
1.靜態(tài)(方法區(qū))存儲
2.棧式存儲
3.堆式存儲
靜態(tài)存儲是指在編譯的時候就得確定這個數(shù)據(jù)的存儲需求,然后給它分配固定的內存,所以說靜態(tài)存儲不允許有可變的數(shù)據(jù)結構出現(xiàn),因為可變的數(shù)據(jù)不會確定存儲空間
棧式存儲相比于靜態(tài)存儲正好相反,在編譯時,棧式存儲指定的存儲數(shù)據(jù)是不確定的,只有真正運行到這個數(shù)據(jù)的時候才知道,那時候才能為它分配內存空間
堆式存儲相對于棧式存儲,棧式存儲在分配空間前必須指定數(shù)據(jù)要分配多少內存,而堆式存儲則完全無法確定數(shù)據(jù)結構需要的內存空間,比如可變數(shù)組,對象實例,所以堆是由大片的可利用塊和空閑塊組成
棧和堆靜態(tài)存儲相對簡單,所以我們著重分析棧和堆的關系和區(qū)別
區(qū)別:
在棧中的數(shù)據(jù)一旦超過它的作用域之后,就會被釋放,內存會被其他數(shù)據(jù)占用
在堆中,分配的內存是由java虛擬機自動垃圾回收器管理,這些可變數(shù)組、對象在沒有引用變量指向他們的時候,才會變成垃圾,但仍然占著內存,之后再一個不確定的時間被垃圾回收器釋放掉
在一個JVM實例中,堆區(qū)只有一個,而棧可以有多個
關系
在堆中創(chuàng)建一個數(shù)據(jù)之后,可以在棧中定義一個變量,這個變量指向堆中的某個數(shù)據(jù)(指向數(shù)據(jù)的首地址),也就是說這個變量變成了堆中數(shù)據(jù)的引用變量,可以利用引用變量來訪問堆中的數(shù)據(jù),這就是java的指針。
并且每個java應有都會有一個JVM實例,每個實例對應一個堆,在這個應有運行期間,所有的類實例和數(shù)組都放在這個堆中,在建立一個對象的時候會從兩個地方分配內存,在堆中是這個對象的實際值,而在棧(堆棧,也叫stack)中,分配的是堆中這個對象的索引
堆棧(stack)先看下這張圖(嗯 畫的很形象)
JVM是基于堆棧的,每新建一個線程會分配一個堆棧,它是以幀為單位,有先進后出的特性(看圖可懂)
當激活一個java方法時,就為往堆棧中放入一個幀(這就是壓棧),在這個方法的執(zhí)行過程中,這個幀就會用來保存數(shù)據(jù)
方法的存在有堆棧決定,而由于先進后出的形式,方法之間嵌套的越深,stack的內存就越難釋放,所以遞歸這樣的方法本人不推薦使用
下面貼出壓棧和出棧的具體實現(xiàn)
使用壓棧出棧來將字符串倒序
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的內存分配方式
覺得還可以的請點個贊,贊不了也可以收藏下;
總之,謝謝閱讀~
文章版權歸作者所有,未經(jīng)允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/68060.html
摘要:方法區(qū)在實際內存空間站可以是不連續(xù)的。這一規(guī)定,可以說是給了虛擬機廠商很大的自由。但是值得注意的是,堆其實還未每一個線程單獨分配了一塊空間,這部分空間在分配時是線程獨享的,在使用時是線程共享的。 在我的博客中,之前有很多文章介紹過JVM內存結構,相信很多看多我文章的朋友對這部分知識都有一定的了解了。 那么,請大家嘗試著回答一下以下問題: 1、JVM管理的內存結構是怎樣的? 2、不同的...
摘要:概要要理解的內存管理策略,首先就要熟悉的運行時數(shù)據(jù)區(qū),如上圖所示,在執(zhí)行程序的時候,虛擬機會把它所管理的內存劃分為多個不同的數(shù)據(jù)區(qū),稱為運行時數(shù)據(jù)區(qū)。 這是一篇有關JVM內存管理的文章。這里將會簡單的分析一下Java如何使用從物理內存上申請下來的內存,以及如何來劃分它們,后面還會介紹JVM的核心技術:如何分配和回收內存。 JMM ( Java Memory Model )概要 show...
摘要:內存溢出的情況就是從類加載器加載的時候開始出現(xiàn)的,內存溢出分為兩大類和。以下舉出個內存溢出的情況,并通過實例代碼的方式講解了是如何出現(xiàn)內存溢出的。內存溢出問題描述元空間的溢出,系統(tǒng)會拋出。這樣就會造成棧的內存溢出。 導言: 對于java程序員來說,在虛擬機自動內存管理機制的幫助下,不需要自己實現(xiàn)釋放內存,不容易出現(xiàn)內存泄漏和內存溢出的問題,由虛擬機管理內存這一切看起來非常美好,但是一旦...
摘要:在一般應用中,不會逃逸的局部對象所占的比例很大,如果能使用棧上分配,那大量的對象就會隨著方法的結束而自動銷毀了,垃圾收集系統(tǒng)的壓力將會小很多。相關參數(shù)設置大對象直接進入年老代的閾值,當對象大小超過這個值時,將直接在年老代分配。 jvm系列 垃圾回收基礎 JVM的編譯策略 GC的三大基礎算法 GC的三大高級算法 GC策略的評價指標 JVM信息查看 GC通用日志解讀 jvm的card t...
閱讀 1118·2021-10-09 09:43
閱讀 18473·2021-09-22 15:52
閱讀 1059·2019-08-30 15:44
閱讀 3050·2019-08-30 15:44
閱讀 3244·2019-08-26 14:07
閱讀 904·2019-08-26 13:55
閱讀 2566·2019-08-26 13:41
閱讀 3087·2019-08-26 13:29