1.java運行時數(shù)據(jù)區(qū),包括堆缕棵,虛擬機棧孵班,程序計數(shù)器,方法區(qū)招驴,本地方法棧
堆:所有對象都在堆中
虛擬機棧:本地變量表篙程,方法出口,動態(tài)鏈接,操作數(shù)棧
程序計數(shù)器:存儲當前線程執(zhí)行到的字節(jié)碼指令的位置
方法區(qū):jVM加載的類信息松忍,靜態(tài)變量桦踊,常量,即時編譯后的代碼
本地方法棧:類似虛擬機棧氮发,不過是調(diào)用本地方法時存的
2.虛擬機回收對象的算法:引用計數(shù)法,可達性分析算法
引用計數(shù)器由于存在對相互引用或者循環(huán)引用的對象雕蔽,無法回收的問題折柠,沒有使用了
可達性分析,判斷GCRoot到對象是否存在一條可以連通的路徑批狐,如果沒有扇售,那表明這個對象可以被回收
什么對象可以作為GCRoot?
1.虛擬機棧中本地變量表引用的對象
2.類里的靜態(tài)變量嚣艇,常量引用的對象
3.本地方法棧中引用的對象
3.堆分為新生代承冰,老年代,默認比例是1:2. 新生代分為eden食零,from困乒,to區(qū),默認比例是8:1:1.
4.永久代:jdk1.8之前有永久代贰谣,存儲方法區(qū)的數(shù)據(jù)娜搂。jdk1.8去掉了永久代迁霎,增加了元空間,meta space百宇,可以動態(tài)擴容考廉,而且是用的堆外內(nèi)存。
5.對象內(nèi)存分配:
直接在eden區(qū)分配:指針碰撞携御,free list(空閑列表)
內(nèi)存工整的話就是指針碰撞的方式昌粤,比如使用serial、parnew等帶有compact的垃圾收集器時啄刹,就是使用指針碰撞方式涮坐。
如果采用CMS這種基于標記-清除的收集器時,就是用空閑列表的方式誓军。
TLAB thread local allocation buffer袱讹,棧上分配,棧獨享的一個空間谭企,其實也在eden區(qū)
6. JVM如何實現(xiàn)跨平臺運?行行同樣的Java bytecode廓译。
JVM會將字節(jié)碼解釋成特定平臺的機器碼然后執(zhí)行,不同的平臺有不同的JVM债查,所以JVM可以跨平臺運行相同的字節(jié)碼非区。
7.?如何調(diào)整JVM堆大小盹廷?
參數(shù) -Xms , -Xmx調(diào)節(jié)堆大小征绸,-Xmn控制堆中新生代大小(堆被劃分為新生代和老年代)俄占,-XX:SurvivorRatio控制新生代中Eden區(qū)和Survivor區(qū)的比例管怠。
如:-Xms20M , -Xmx20M,-Xmn10M, -XX:SurvivorRatio=8. 表示堆大小是20M,其中新生代10M缸榄,Eden區(qū)8M渤弛,from survivor 1M,to survivor 1M甚带,新生代總可用空間是9M(一個Eden區(qū)+1個survivor區(qū)總量)
8. client她肯、-server參數(shù)有什什么區(qū)別?
-Server模式啟動時鹰贵,速度較慢,但運行起來后性能將會有很大提升晴氨,原因是:當虛擬機在-Client模式的時候,使用的是一個代號為C1的輕量級編譯器碉输,而-Server模式啟動的虛擬機采用相對重量級代號為C2的編譯器籽前,C2比C1編譯器編譯的相對徹底,服務(wù)起來之后,性能高枝哄。
server:啟動慢肄梨,編譯更完全,編譯器是自適應(yīng)編譯器膘格,效率高峭范,針對服務(wù)端應(yīng)用優(yōu)化财松,在服務(wù)器環(huán)境中最大化程序執(zhí)行速度而設(shè)計瘪贱。client:快速啟動,內(nèi)存占用少辆毡,編譯快菜秦,針對桌面應(yīng)用程序優(yōu)化,為在客戶端環(huán)境中減少啟動時間而優(yōu)化舶掖;
9. 你知道哪些或者你們先上使用什么GC策略球昨?它有什么優(yōu)勢、使用與什么場景眨攘?
? ? ? 線上使用G1垃圾回收器主慰,G1是并行也并發(fā)執(zhí)行的垃圾收集器,而且會整理空間碎片鲫售,比較適合追求低停頓的多cpu共螺、內(nèi)存大的應(yīng)用。
? ? ? G1結(jié)合了CMS的優(yōu)勢情竹,可以與用戶線程并發(fā)執(zhí)行來達到低停頓藐不,同時也改進了CMS會存在內(nèi)存空間碎片的缺點。
? ? ? G1將整個java堆劃分成多個大小相同的region秦效,會追蹤每個區(qū)的垃圾回收價值雏蛮,每次根據(jù)允許的垃圾回收時間,選擇回收價值最大的區(qū)域進行回收阱州。
? ? ? 回收策略也分yongGC挑秉、mixedGC、fullGC:
? ? ? 新生代滿了觸發(fā)yongGC
? ? ? 當老年代old region的對象越來越多苔货,為避免老年代內(nèi)存占滿犀概,會觸發(fā)mixedGC,回收新生代和部分老年代region蒲赂。
? ? ? 如果老年代還是滿了阱冶,(mixedGC無法跟上內(nèi)存分配的速度)就會fullGC,是使用serial old來收集整個GC堆滥嘴。
? ? ? (ParallelgC的特點是追求高吞吐量木蹬,適合跟用戶交互少、計算量大的服務(wù))
? ? ? ? (CMS的特點是降低用戶線程停頓時間,適合追求低停頓的應(yīng)用)
10. 永久代保存的是什么數(shù)據(jù)镊叁?會引起outofmemory嗎尘颓?
? ? ? 保存的是方法區(qū)的數(shù)據(jù),會晦譬。在jdk1.8已經(jīng)沒有永久代疤苹,用元空間來存儲方法區(qū)的數(shù)據(jù),元空間是在分配的堆外內(nèi)存(本地內(nèi)存)敛腌,可以自動擴容卧土。
11. 你有沒有遇到過outofmemory問題?怎么處理的像樊?有哪些收貨尤莺?
? ? 先根據(jù)錯誤日志來確定具體是哪個地方內(nèi)存溢出,jvm的運行時數(shù)據(jù)區(qū)出了程序計數(shù)器以外生棍,其他的幾個區(qū)如堆颤霎、方法區(qū)、棧都可能內(nèi)存溢出涂滴。? 更多的還是堆內(nèi)存溢出和方法區(qū)友酱。 一般堆內(nèi)存溢出可能的情況是有大對象收集不了,比如緩存太大柔纵。還有循環(huán)產(chǎn)生太多對象缔杉,如果程序沒問題可以考慮加大內(nèi)存。
? ? 方法區(qū)存的是jvm加載的類信息首量、常量壮吩、靜態(tài)變量,如果加載的類太多卸載不了也會產(chǎn)生內(nèi)存溢出加缘。比如大量的jsp鸭叙,會被編譯成class文件。 這種情況一般還是加內(nèi)存
12. jstack 是?什么的? jstat 呢拣宏?
? jstack生成當前線程dump信息
? jmap生成堆dump信息
? jstat 查看虛擬機的一些統(tǒng)計信息沈贝,比如gc信息
? jps查看正在運行的虛擬機進程
?13.? 如果線上程序周期性地出現(xiàn)卡頓,你懷疑可 能是 GC 導致的勋乾,你會怎么來排查這個問題宋下?線程?志?般你會看其中的什么 部分?
? 周期性的卡頓可能是GC導致辑莫,需要輸出堆dump文件具體分析学歧,可以用mat工具來查看占用內(nèi)存最多的一些大對象,然后查看引用各吨,確定代碼, 再確認是否有問題枝笨。
? 線程日志主要看wait、block的線程,是否有大量線程在等待横浑、或者被其他線程占用鎖了導致阻塞
14剔桨、StackOverflow異常有沒有遇到過??般你猜測會在什么情況下被觸發(fā)徙融?如何指定?個線程的堆棧??洒缀??般你們寫多少?
? ? ? 棧里存儲的是棧幀欺冀,棧幀過大或者棧幀過多树绩,導致棧內(nèi)存不夠,都會出現(xiàn)stackoverflow異常
? ? ? 棧幀存儲的是當前線程正在運行的方法的數(shù)據(jù):本地變量表脚猾、方法出口等這些信息葱峡。
? ? ? 如方法里變量太多,棧幀就會比較大龙助。
? ? ? 方法如果遞歸調(diào)用層次太深,棧幀就會太多蛛芥。
? ? ? 沒手動設(shè)置過棧的大小提鸟。java棧容量參數(shù)設(shè)置:-Xss,查了下默認值貌似是1M仅淑? 不確定
15. Minor GC什么情況下產(chǎn)生称勋?
新生代的Eden區(qū)空間不夠分配時,將進行Minor GC涯竟。Minor GC把新生代中能清理的對象清理掉赡鲜,如果空間還是不夠分配對象,那么將會把Eden區(qū)中存活的對象移動到Survivor區(qū)(如果Survivor區(qū)能夠容納)庐船,并且對象年齡+1.? 如果Survivor區(qū)不能容納银酬,會通過分配擔保機制提前移動到老年代。
16. FullGC什么情況下產(chǎn)生筐钟?
1.在Minor GC之前揩瞪,會檢查老年代剩余空間是否足夠存放新生代對象總大小(或者歷次晉升的平均大新ǔ濉)李破,不夠的話,就進行FullGC壹将。
2.大對象直接進入老年代嗤攻,如果老年代沒有足夠的連續(xù)空間,會導致內(nèi)存還有不少空間時诽俯,提前觸發(fā)FullGC
換句話說妇菱,老年代空間不夠了(老年代在新生代對象轉(zhuǎn)入以及創(chuàng)建大對象、大數(shù)組時才會不足),會進行FullGC
17. 頻繁FullGC恶耽,可能的原因密任?
1.老年代回收效果不好,可能是有大對象駐留偷俭,不能被清理浪讳,比如用作緩存的map等
2.經(jīng)常有大對象生成,即使有空間涌萤,但是沒有連續(xù)空間來分配
18. 什么情況下OutOfMemoryError淹遵?原因?出錯時如何查看dump日志负溪?
FullGC后透揣,空間仍然不夠,就會內(nèi)存溢出川抡。
原因:JVM運行時數(shù)據(jù)區(qū)包括程序計數(shù)器辐真、堆、虛擬機棧崖堤、本地方法棧侍咱、方法區(qū)。
除了程序計數(shù)器以外密幔,其他數(shù)據(jù)區(qū)都可能拋出outOfMemoryError楔脯。參考11題
可以在啟動時加-XX:HeapDumpOnOutOfMemoryError參數(shù)
19. 輸出堆dump常用參數(shù):
-XX:+HeapDumpBeforeFullGC
-XX:HeapDumpPath=.
-Xloggc:gc.log
-XX:+PrintGC
-XX:+PrintGCDetails
-XX:+PrintGCDateStamps
-XX:+UseGCLogFileRotation
-XX:NumberOfGCLogFiles=10
-XX:GCLogFileSize=100m
-XX:HeapDumpOnOutOfMemoryError
20.垃圾收集器