JVM原理:
JVM是java核心和基礎(chǔ)尽超,在Java編譯器和OS平臺之間的虛擬處理器官撼。他可以在上面執(zhí)行java的字節(jié)碼程序,java編譯器只要面向jvm似谁,生成JVM能理解的代碼或字節(jié)碼文件傲绣。Java源文件經(jīng)編譯成字節(jié)碼程序掠哥,通過JVM將每一條指令翻譯成不同平臺的機(jī)器碼,通過特定平臺運(yùn)行秃诵。
JVM體系結(jié)構(gòu):
類加載器:加載class文件续搀;
執(zhí)行引擎:執(zhí)行字節(jié)碼或者執(zhí)行本地方法
運(yùn)行時數(shù)據(jù)區(qū):包括方法區(qū)、堆顷链、Java棧目代、PC寄存器、本地方法棧
一嗤练、解釋
1榛了、PC寄存器:用于存儲每個線程下一步將執(zhí)行的JVM指令。
2煞抬、棧:棧是線程私有的霜大,每個線程創(chuàng)建的同時都會創(chuàng)建JVM棧,JVM棧中存放當(dāng)前線程中的局部基本類型的變量革答。
3战坤、堆:它是JVM用來存儲對象實例以及數(shù)組值的區(qū)域。堆中對象的內(nèi)存需要等待GC進(jìn)行回收残拐。堆是JVM所有線程共享的途茫。
4、方法區(qū):存放了所加載的類信息溪食、類中的靜態(tài)變量囊卜、類中定義為final類型的常量、類中的Field信息错沃、類中的方法信息栅组;通過class對象中的getName等方法來獲取信息時,實際這些數(shù)據(jù)是來源于方法區(qū)枢析,方法區(qū)是全局共享的玉掸。
5、運(yùn)行時常量池:存放類中固定的常量信息醒叁、方法和Field的引用信息等司浪,其空間是從方法區(qū)中分配。
6辐益、本地方法棧:JVM采用本地方法棧來支持native方法的執(zhí)行断傲,此區(qū)域用于存儲每個native方法調(diào)用的狀態(tài)。
二智政、如何判斷對象是否存活:
1认罩、引用計數(shù)法:給對象中添加一個引用計數(shù)器,當(dāng)一個地方引用了對象续捂,計數(shù)加1垦垂;當(dāng)引用失效時宦搬,計算器減1;當(dāng)計算器為0的時候劫拗,表示該對象已死间校,可回收;但是很難解決循環(huán)引用問題页慷。
2憔足、可達(dá)性分析:通過一些列稱為“GC ROOT”的對象作為起點(diǎn),從這些節(jié)點(diǎn)開始向下搜索酒繁,搜索所走過的路徑稱為引用鏈滓彰,當(dāng)一個對象GC Roots沒有任何引用鏈相連,則證明此對象已死州袒,可回收揭绑。java中可以作為GC Roots的對象包括:虛擬機(jī)棧中引用的對象、本地方法棧中native方法引用的對象郎哭、方法區(qū)靜態(tài)屬性引用的對象他匪、方法區(qū)中常量引用的對象。
三夸研、JVM垃圾回收
1邦蜜、對新生代的對象的收集叫 minor GC;
2、對老年代的對象的收集叫 full GC亥至;
3畦徘、程序中主動調(diào)用System.gc()強(qiáng)制執(zhí)行的GC 為 full GC;
4、強(qiáng)引用:默認(rèn)情況下抬闯,對象采用的均為強(qiáng)引用;如果一個對象具有強(qiáng)引用关筒,垃圾回收器不會回收它溶握,當(dāng)內(nèi)存空間不足,虛擬機(jī)寧愿拋出OutOfMemoryError蒸播,也不會回收具有強(qiáng)引用的對象睡榆。
5、軟引用:適用于緩存場景(只有內(nèi)存不夠用的情況下才會被回收)
6袍榆、弱引用 : 在GC時一定會被GC回收
7胀屿、虛引用:用于判斷對象是否被GC。如果一個對象只具有虛引用包雀,那么它就和沒有任何引用一樣宿崭,隨時會被JVM當(dāng)做垃圾回收。
四才写、垃圾收集算法
1葡兑、標(biāo)記-清除算法:有兩點(diǎn)不足奖蔓,一個效率問題,標(biāo)記和清除過程效率都不高讹堤。一個是空間問題吆鹤,標(biāo)記清除后會產(chǎn)生大量不連續(xù)的內(nèi)存碎片。
2洲守、復(fù)制算法:解決了內(nèi)存碎片問題疑务,但是內(nèi)存利用率低
3、標(biāo)記整理法:解決了內(nèi)存碎片問題
4梗醇、分代收集算法
(1)新生代:在新生代中知允,由于對象生存期短,每次回收都會有大量對象死去婴削,那么這時就采用復(fù)制算法
(2)老年代:老年代里的對象存活率較高廊镜,沒有額外的空間進(jìn)行分配擔(dān)保,所以可以使用標(biāo)記-整理 或者 標(biāo)記-清除唉俗。
六嗤朴、垃圾收集器
1、Serial收集器(串行收集器):單線程收集虫溜,并且在收集的時候必須暫停所有工作線程雹姊;
2、CMS收集器:
Concurrent-Mark-Sweeo的縮寫衡楞,并發(fā)的標(biāo)價與清除
收集器是一種以獲取最短回收停頓時間為目標(biāo)的收集器吱雏;基于標(biāo)記清除算法,并發(fā)收集瘾境、低停頓歧杏、運(yùn)作過程復(fù)雜(初始標(biāo)記、并發(fā)標(biāo)記迷守、重新標(biāo)記犬绒、并發(fā)清除)。CMS收集器有3個缺點(diǎn):
(1)對CPU資源非常敏感(占用資源)兑凿;
(2)無法處理浮動垃圾(在并發(fā)清除時凯力,用戶線程新產(chǎn)生的垃圾叫浮動垃圾),可能出現(xiàn)Concurrent Mode Failure失敗
(3)產(chǎn)生大量的內(nèi)存碎片礼华。
CMS只有在觸發(fā)FullGC的情況下才會對堆空間進(jìn)行compact咐鹤。
如果現(xiàn)實應(yīng)用長時間進(jìn)行,碎片化會非常嚴(yán)重圣絮,會很容易造成promotion failed.為了結(jié)局這個問題祈惶,線上很多應(yīng)用通過定期重啟或者受到觸發(fā)FullGC來觸發(fā)碎片整理。
3、G1收集器
特點(diǎn):(1)分代收集:G1可以不需要其他GC收集器的配合就能獨(dú)立管理整個堆行瑞,采用不同的方式處理新生對象和已經(jīng)存活一段時間的對象奸腺;
(2)空間整合:采用標(biāo)記整理算法,局部采用復(fù)制算法血久,不會有內(nèi)存碎片突照,不會應(yīng)為大對象找不到足夠的連續(xù)空間而提前觸發(fā)GC;
(3)可預(yù)測的停頓:能夠讓使用者明確指定一個時間片段內(nèi)氧吐,消耗在垃圾收集上的時間不超過時間范圍內(nèi)讹蘑。
-XX:+UseG1GC
4、并行收集器:這是JVM默認(rèn)的收集器筑舅,它最大的優(yōu)點(diǎn)是使用多個線程來掃描和壓縮堆座慰。缺點(diǎn)是minor和full GC的時候都會暫停應(yīng)用的運(yùn)行。并行收集器最適合用再可以容忍程序停滯的環(huán)境使用翠拣,它占用較低的CPU因而能提高對應(yīng)的吞吐版仔。
-XX:+UseParallelGC
七、Java的內(nèi)存模型
主內(nèi)存
工作內(nèi)存
八误墓、雙親委派模型
九蛮粮、JVM類加載
十、內(nèi)存泄露和內(nèi)存溢出
內(nèi)存泄露:指程序在申請內(nèi)存后谜慌,無法釋放已申請的內(nèi)存空間
內(nèi)存溢出:指程序在申請內(nèi)存時然想,沒有足夠的內(nèi)存空間供其使用,出現(xiàn)out of memory
出現(xiàn)內(nèi)存泄露的情況:
1欣范、靜態(tài)集合類
2变泄、各種連接沒有被釋放
3、監(jiān)聽器
4恼琼、變量不合理的作用域
5妨蛹、單例模式可能會造成內(nèi)存泄露
內(nèi)存溢出的情況(OOM):
1、內(nèi)存中加載的數(shù)據(jù)量過大晴竞,如一次取出過多數(shù)據(jù)
2滑燃、集合類中有對對象的引用,使用完后未清空颓鲜,使得JVM不能回收
3、代碼中存在死循環(huán)或者循環(huán)產(chǎn)生過多重復(fù)的對象實體
4典予、啟動參數(shù)內(nèi)存值設(shè)定的過小甜滨。
十一、內(nèi)存屏障
十二瘤袖、訪問對象時衣摩,如何定位到該對象