java編程中的堆與棧,你了解多少?

在JVM中內(nèi)存有這5類


堆(Heap)

存放關(guān)鍵字new創(chuàng)建的對象和數(shù)組;

java堆是jvm內(nèi)存管理中最大的一塊,線程共享;

當(dāng)使用new創(chuàng)建對象時(shí),不必指定分配空間的大小,jvm會(huì)動(dòng)態(tài)自動(dòng)分配一塊區(qū)域;在程序執(zhí)行過程中,沒有指向此對象的引用時(shí),此對象就被標(biāo)記為可被回收狀態(tài),將由GC(垃圾回收器)在一個(gè)不確定的時(shí)間自動(dòng)回收,釋放所占的內(nèi)存空間。

在jvm啟動(dòng)的時(shí)候創(chuàng)建。此區(qū)域唯一目的就是存放對象實(shí)例,幾乎所有的對象實(shí)例都在這里分配內(nèi)存。但是隨著JIT編譯器(即時(shí)編譯器)的發(fā)展與逃逸分析技術(shù)的逐漸成熟,棧上分配、標(biāo)量替換優(yōu)化技術(shù)將會(huì)導(dǎo)致一些微妙變化(對象可能會(huì)分配到棧上),所以這種所有對象都分配在堆上也不是那么絕對的。

虛擬機(jī)棧(VM Stack)

存放8種基本類型的數(shù)據(jù)和對象引用(不是對象)。

每個(gè)線程有自己的單獨(dú)的棧。

先進(jìn)后出,后進(jìn)先出。小編推薦一個(gè)學(xué)JAVA的學(xué)習(xí)裙【 一三三,九三零,六九三】,無論你是大牛還是小白,是想轉(zhuǎn)行還是想入行都可以來了解一起進(jìn)步一起學(xué)習(xí)!裙內(nèi)有開發(fā)工具,很多干貨和技術(shù)資料分享!

因?yàn)橹饕娣呕绢愋蛿?shù)據(jù)變量,所以分配空間比堆快。當(dāng)超出變量的作用域,將由編譯器立即釋放空間。

本地方法棧(Native Method Stack)

程序調(diào)用本地方法的內(nèi)存區(qū)域。

程序計(jì)數(shù)器 (Program Counter Register)

一塊較小的內(nèi)存空間,可看作是當(dāng)前線程所執(zhí)行的字節(jié)碼的 行號(hào)指示器。

通過改變計(jì)數(shù)器的值來選取下一條需要執(zhí)行的字節(jié)碼指令。(分支、循環(huán)、跳轉(zhuǎn)、異常處理、線程恢復(fù)等)基礎(chǔ)功能都依賴與其完成。

特點(diǎn):

線程私有:因?yàn)?Java 虛擬機(jī)的多線程是通過 線程輪流切換 并 分配處理器執(zhí)行時(shí)間 來實(shí)現(xiàn)的,在某一時(shí)刻,只會(huì)執(zhí)行一條線程。因此,為了線程切換后能恢復(fù)到正確的執(zhí)行位置,每條線程都需要有一個(gè)獨(dú)立的程序計(jì)數(shù)器。

無內(nèi)存溢出:如果線程正在執(zhí)行的是一個(gè) Java 方法,這個(gè)計(jì)數(shù)器記錄的是正在 執(zhí)行的虛擬機(jī)字節(jié)碼指令的地址;如果正在執(zhí)行的是 Native 方法,這個(gè)計(jì)數(shù)器值則為空(Undefined)。此內(nèi)存區(qū)域是唯一一個(gè)在 Java 虛擬機(jī)程序規(guī)范中沒有規(guī)定任何 OutOfMemoryError 情況的區(qū)域。

小編推薦一個(gè)學(xué)JAVA的學(xué)習(xí)裙【 一三三,九三零,六九三】,無論你是大牛還是小白,是想轉(zhuǎn)行還是想入行都可以來了解一起進(jìn)步一起學(xué)習(xí)!裙內(nèi)有開發(fā)工具,很多干貨和技術(shù)資料分享!方法區(qū)(Method Area)

跟堆一樣,被所有的線程共享。

在裝載類文件時(shí),用于存儲(chǔ)類型信息(類的描述信息):

是一個(gè)內(nèi)存邏輯區(qū)域,是JVM在裝載類文件時(shí),用于存儲(chǔ)類型信息(類的描述信息):

運(yùn)行時(shí)常量池:在方法區(qū)中,每個(gè)類型都對應(yīng)一個(gè)常量池,存放該類型所用到的所有常量,常量池中存儲(chǔ)了諸如文字字符串、final變量值、類名和方法名常量。它們以數(shù)組形式通過索引被訪問,是外部調(diào)用與類聯(lián)系及類型對象化的橋梁。(存的可能是個(gè)普通的字符串,然后經(jīng)過常量池解析,則變成指向某個(gè)類的引用)

字段信息:字段信息存放類中聲明的每一個(gè)字段的信息,包括字段的名、類型、修飾符。

字段名稱指的是類或接口的實(shí)例變量或類變量,字段的描述符是一個(gè)指示字段的類型的字符串,如private A a=null;則a為字段名,A為描述符,private為修飾符。

方法信息:類中聲明的每一個(gè)方法的信息,包括方法名、返回值類型、參數(shù)類型、修飾符、異常、方法的字節(jié)碼。

(在編譯的時(shí)候,就已經(jīng)將方法的局部變量、操作數(shù)棧大小等確定并存放在字節(jié)碼中,在裝載的時(shí)候,隨著類一起裝入方法區(qū)。)

靜態(tài)成員變量:類中的靜態(tài)成員變量和靜態(tài)代碼塊。

到類classloader的引用:到該類的類裝載器的引用。

到類class的引用:虛擬機(jī)為每一個(gè)被裝載的類型創(chuàng)建一個(gè)class實(shí)例,用來代表這個(gè)被裝載的類。

每個(gè)類的全限定名

每個(gè)類的直接超類的全限定名(可約束類型轉(zhuǎn)換)

該類是類還是接口

該類型的訪問修飾符小編推薦一個(gè)學(xué)JAVA的學(xué)習(xí)裙【 一三三,九三零,六九三】,無論你是大牛還是小白,是想轉(zhuǎn)行還是想入行都可以來了解一起進(jìn)步一起學(xué)習(xí)!裙內(nèi)有開發(fā)工具,很多干貨和技術(shù)資料分享!

直接超接口的全限定名的有序列表

類的基本信息:

已裝載類的詳細(xì)信息:

棧是運(yùn)行時(shí)的單位,而堆是存儲(chǔ)的單位。

總結(jié)堆與棧的關(guān)系

棧是運(yùn)行時(shí)的單位,而堆是存儲(chǔ)的單位。

堆和棧中,棧是程序運(yùn)行最根本的東西。程序運(yùn)行可以沒有堆,但是不能沒有棧。而堆是為棧進(jìn)行數(shù)據(jù)存儲(chǔ)服務(wù),說白了堆就是一塊共享的內(nèi)存。不過,正是因?yàn)槎押蜅5姆蛛x的思想,才使得Java的垃圾回收成為可能。

小編推薦一個(gè)學(xué)JAVA的學(xué)習(xí)裙【 一三三,九三零,六九三】,無論你是大牛還是小白,是想轉(zhuǎn)行還是想入行都可以來了解一起進(jìn)步一起學(xué)習(xí)!裙內(nèi)有開發(fā)工具,很多干貨和技術(shù)資料分享!

Java中,棧的大小通過-Xss來設(shè)置,當(dāng)棧中存儲(chǔ)數(shù)據(jù)比較多時(shí),需要適當(dāng)調(diào)大這個(gè)值,否則會(huì)出現(xiàn)java.lang.StackOverflowError異常。常見的出現(xiàn)這個(gè)異常的是無法返回的遞歸,因?yàn)榇藭r(shí)棧中保存的信息都是方法返回的記錄點(diǎn)。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容