Java內(nèi)存內(nèi)存區(qū)域圖
內(nèi)存泄露和內(nèi)存溢出的區(qū)別
- 內(nèi)存泄露是指分配出去的內(nèi)存沒有被回收回來
- 內(nèi)存溢出是指程序所需要的內(nèi)存超出了系統(tǒng)所能分配的內(nèi)存(包括動(dòng)態(tài)擴(kuò)展)的上限依许。
程序計(jì)數(shù)器
作用:
記錄當(dāng)前線程要執(zhí)行下一條的指令念逞。
為什么會(huì)有它蟀架?
單核CPU在某一時(shí)刻只會(huì)執(zhí)行一個(gè)線程中的一條指令凶硅,那么多個(gè)線程會(huì)輪流獲得CPU執(zhí)行權(quán)掸哑,因此每個(gè)線程都需要有一個(gè)私有的程序計(jì)數(shù)器來記錄唇撬。
JVM中規(guī)定兰英,如果線程中執(zhí)行 的是Java方法,則程序計(jì)數(shù)器中保存的是線程需要執(zhí)行指令的地址蜗搔,如果是Native方法劲藐,則程序計(jì)數(shù)器中的值是Unefined。
虛擬機(jī)棧(Java棧)
什么是幀棧樟凄?
每個(gè)方法被調(diào)用的時(shí)候都會(huì)同時(shí)創(chuàng)建一個(gè)容器聘芜,該容器存放的是
函數(shù)執(zhí)行時(shí)所需要的數(shù)據(jù)(局部變量表,方法返回地址,動(dòng)態(tài)連接(方法所屬的類的運(yùn)行時(shí)常量池的引用)等等)缝龄,這個(gè)容器就稱為棧幀
作用
它是用于支持虛擬機(jī)中線程進(jìn)行方法調(diào)用和方法執(zhí)行的數(shù)據(jù)結(jié)構(gòu)
執(zhí)行引擎每調(diào)用一個(gè)函數(shù)時(shí)厉膀,就為這個(gè)函數(shù)創(chuàng)建一個(gè)棧幀,并加入虛擬機(jī)棧二拐。即每個(gè)函數(shù)從調(diào)用到執(zhí)行結(jié)束服鹅,對(duì)應(yīng)著棧幀的入棧和出棧。
本地方法棧
該區(qū)域與虛擬機(jī)棧所發(fā)揮的作用非常相似百新,只是虛擬機(jī)棧為虛擬機(jī)執(zhí)行Java方法服務(wù)企软,而本地方法棧為執(zhí)行本地(Native)方法服務(wù)。
Java堆
Java堆饭望,是Java虛擬機(jī)管理的最大的一塊內(nèi)存仗哨,也是GC的主戰(zhàn)場(chǎng)。
作用
用于存儲(chǔ)對(duì)象本身以及數(shù)組(數(shù)組引用放在Java棧中)
其它
從內(nèi)存回收角度铅辞,Java堆被分為新生代和老年代厌漂;這樣劃分的好處是為了更快的回收內(nèi)存;
堆中的垃圾回收歷程斟珊?苇倡??
方法區(qū)
作用
存儲(chǔ)已被虛擬機(jī)加載的類信息、常量旨椒、靜態(tài)變量晓褪、編譯器編譯后的代碼等數(shù)據(jù)
運(yùn)行時(shí)常量池
方法區(qū)有非常重要的部分是運(yùn)行時(shí)常量池,用于存放編譯器生成的各種字面量和符號(hào)引用综慎。運(yùn)行時(shí)常量池除了編譯期產(chǎn)生的Class文件的常量池涣仿,還可以在運(yùn)行期間,將新的常量加入常量池示惊。
例如說下面這個(gè)例子:
String s = "abc"; 先在常量池中尋找常量“abc”好港,如果沒有,則將“abc”放到運(yùn)行時(shí)常量池米罚,將引用賦值給s媚狰,如果存在,則直接把賦值給s阔拳。
字面量和符號(hào)引用是什么崭孤?
- 字面量:與Java語(yǔ)言層面的常量概念相近,包含文本字符串糊肠、聲明為final的常量值等辨宠。
- 符號(hào)引用,編譯語(yǔ)言層面的概念:
- 類和接口的全限定名
- 字段和方法的名稱和描述符