一洽沟、jvm內(nèi)存區(qū)域
以前的認(rèn)知以故,jvm的內(nèi)存就只有堆和棧,堆就只是存放對象的地址的地方裆操,棧是方法的執(zhí)行的地方怒详。讀完這一篇,在認(rèn)知上拓寬了內(nèi)存區(qū)域更詳細(xì)些的認(rèn)知踪区;
堆還是原來的堆的理解昆烁,棧可分為虛擬機(jī)棧和本地方法棧缎岗,不過通常native方法用的比較少静尼,大多與JNI交互時(shí)用的會(huì)比較多,所以普通方法都是在虛擬機(jī)棧上處理。與原來認(rèn)知大徑相同鼠渺。多了一個(gè)方法區(qū)和程序計(jì)數(shù)器的概念蜗元;
堆
這塊區(qū)域隨著虛擬機(jī)啟動(dòng)而創(chuàng)建,存放所有的對象實(shí)例和數(shù)組系冗。這塊區(qū)域也是GC需要特別關(guān)注的地方。堆里的細(xì)分:新生代薪鹦,老生代掌敬,永久代(Hotspot的永久代就是方法區(qū))。新生代還可分為池磁,Eden奔害,S1,S2地熄。
方法區(qū)
線程共享區(qū)域华临,存儲(chǔ)已被虛擬機(jī)加載的類信息、常量端考、靜態(tài)變量雅潭。(Hotspot用永久代實(shí)現(xiàn)了方法區(qū)) 方法區(qū)還包含運(yùn)行時(shí)常量池下文做介紹
程序計(jì)數(shù)器
每個(gè)線程獨(dú)立擁有的,當(dāng)前線程所執(zhí)行的字節(jié)碼的行號指示器却特,怎么理解呢扶供?執(zhí)行一個(gè)Java方法,那么寄存器里面記錄的就是正在執(zhí)行的虛擬機(jī)字節(jié)碼指令的地址
虛擬機(jī)棧
線程在創(chuàng)立的時(shí)候裂明,就會(huì)初始化一個(gè)空的棧幀隊(duì)列椿浓,每個(gè)方法在執(zhí)行的時(shí)候都會(huì)創(chuàng)建一個(gè)棧幀用于存儲(chǔ)局部變量表、操作數(shù)棧闽晦、方法出口等信息扳碍,然后入到這個(gè)隊(duì)列中,每一個(gè)方法從調(diào)用到執(zhí)行完成仙蛉,一個(gè)棧幀入棧和出棧的過程笋敞。
本地方法棧
和虛擬機(jī)棧類似,存儲(chǔ)Native方法的相關(guān)信息捅儒。
運(yùn)行時(shí)常量池
運(yùn)行時(shí)常量池其實(shí)是方法區(qū)的一部分液样,之前在class學(xué)習(xí)中,有看到常量池的內(nèi)容巧还,即當(dāng)class解析出來的常量池鞭莽,將會(huì)放在這個(gè)區(qū)域儲(chǔ)存。直接引用和符號引用一并儲(chǔ)存麸祷,(還是沒解答這兩個(gè)區(qū)別)澎怒。另外它還有個(gè)特性,具有動(dòng)態(tài)性,在運(yùn)行期間可將新的常量放入池中喷面,例如String 的intern方法星瘾;JDK7之后,Hotspot虛擬機(jī)便將運(yùn)行時(shí)常量池從永久代移除了惧辈。
直接內(nèi)存
看到這個(gè)一臉懵逼琳状,我的理解,就是jvm單獨(dú)分出了一塊堆外內(nèi)存盒齿,用于native堆與java堆之間的數(shù)據(jù)交互等念逞。沒用過,理解不深
二边翁、垃圾回收
看到這一章前言翎承,感覺很深刻啊,內(nèi)存動(dòng)態(tài)分配和垃圾回收是Java與C++之間的一道圍墻符匾,里面的人想出去叨咖,外面的人想進(jìn)來。
首頁啊胶,垃圾顧名思義甸各,就是不要的東西,在內(nèi)存中创淡,那些東西是算"不要了"的東西痴晦;以何依據(jù)?
1琳彩、引用計(jì)數(shù)算 :每當(dāng)一個(gè)對象被引用則計(jì)數(shù)+1誊酌,失效-1,計(jì)數(shù)為0則就算垃圾
2露乏、可達(dá)性分析算法:"GC Roots”的對象作為起始點(diǎn),一個(gè)對象到該對象的引用鏈不相通碧浊,則就算垃圾
引用
強(qiáng)引用:即
Object obj = new Object();
軟引用(SoftReference): 內(nèi)存不足時(shí),將會(huì)回收這些對象的內(nèi)存
弱引用(WeakReference): 只要垃圾回收線程掃描到該對象瘟仿,無關(guān)內(nèi)存時(shí)候充足箱锐,都會(huì)回收
虛引用(PhantomReference):虛引用必須和引用隊(duì)列(ReferenceQueue)聯(lián)合使用,再回收對象之前劳较,如果是虛引用對象驹止,可以在回收之前做一些必要的操作
垃圾回收算法
1、標(biāo)記 - 清除算法
2观蜗、復(fù)制算法
3臊恋、標(biāo)記 - 整理算法
4、分代收集算法
垃圾收集器
Serial收集器: 串行收集器. “單線程”操作墓捻,進(jìn)行垃圾回收時(shí)抖仅,暫停其他所有的工作線程( "Stop The World" )特點(diǎn):簡單高效
ParNew收集器:Serial收集器的多線程版本,還是會(huì)出現(xiàn) ( "Stop The World" ),只是時(shí)間比較短
Parallel Scavenge收集器:類似于ParNew 收集器撤卢,吞吐量(運(yùn)行用戶代碼的時(shí)間與CPU總消耗時(shí)間的比值环凿。特點(diǎn):可通過參數(shù)手動(dòng)調(diào)節(jié)( "Stop The World" )時(shí)間
Serial Old收集器: Serial收集器的老年代版本
Parallel Old收集器:Parallel Scavenge收集器的老年代版本
-
CMS收集器:以獲取最短回收停頓時(shí)間為目標(biāo)的收集器,特點(diǎn):并發(fā)收集、低停頓放吩。三缺點(diǎn):
對CPU資源敏感智听;
無法處理浮動(dòng)垃圾;
它使用的回收算法-“標(biāo)記-清除”算法會(huì)導(dǎo)致收集結(jié)束時(shí)會(huì)有大量空間碎片產(chǎn)生
G1收集器(Garbage-First):面向服務(wù)器的垃圾收集器,極高概率滿足GC停頓時(shí)間要求的同時(shí),還具備高吞吐量性能特征
三渡紫、對象存儲(chǔ)策略
-
新對象優(yōu)先在eden區(qū)分配:
老年代GC(Full GC)速度比新生代GC(Minor GC)慢10倍以上瞭稼,另外eden區(qū)域滿了之后,就出發(fā)一次GC腻惠,如果某些對象經(jīng)過幾輪GC后沒死,將會(huì)進(jìn)入到S1區(qū)域欲虚,S1滿了GC幾次后進(jìn)入到S2集灌。
-
大對象直接進(jìn)入老年代,
大對象就是需要大量連續(xù)內(nèi)存空間的對象(比如:字符串复哆、數(shù)組)欣喧。為了避免為大對象分配內(nèi)存時(shí)由于分配擔(dān)保機(jī)制帶來的復(fù)制而降低效率。
-
長期存活對象也進(jìn)入老年代梯找。
上述GC到S2之后 對象還沒死唆阿,則將該對象放入老年代,默認(rèn)狀態(tài)下GC15次锈锤,未被殺死驯鳖。
-
動(dòng)態(tài)對象年齡判定
為了更好的適應(yīng)不同程序的內(nèi)存情況,虛擬機(jī)不是永遠(yuǎn)要求對象年齡必須達(dá)到了某個(gè)值才能進(jìn)入老年代久免,如果 Survivor 空間中相同年齡所有對象大小的總和大于 Survivor 空間的一半浅辙,年齡大于或等于該年齡的對象就可以直接進(jìn)入老年代,無需達(dá)到要求的年齡阎姥。