在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)。
