相關(guān)面試題:

計算機組成

a=2+3 2,3從內(nèi)存拿到cpu -> 計算->結(jié)果放到內(nèi)存
操作系統(tǒng)管理線程的調(diào)度,os把app的線程指令扔到cpu
調(diào)度策略,最常見的cfs
線程數(shù)不一定越多越好,線程切換


CAS compare and swap
在JDK中的應(yīng)用,原子類 do{}while(!cas)

ABA問題解決
增加一個版本號,讀取和版本號,修改版本號,比較版本號,也可以用boolean值來標記是否改過。
CAS底層實現(xiàn)
unsafe類中的本地方法,compareandswap



java內(nèi)存布局
對象頭:markword 、 calss pointer 、 數(shù)組長度
實例數(shù)據(jù):
對齊填充
可以用以下工具查看


指針壓縮
+UseCompressedClassPointer 頭部指針壓縮
+UseCompressedOops 普通指針壓縮 比如對象屬性里面的指針
Object o = new Obeject();占幾個字節(jié)?
默認開啟了指針壓縮:
markword - 8 klasspointer - 4 對齊填充 - 4 --------------------- 16字節(jié)
沒有開啟指針壓縮:
markword - 8 klasspointer - 8 --------------------------------------- 16字節(jié)
boolean byte 1
char short 2
int float 4
long double 8
string 4普通指針壓縮 未開啟 8
synchronized
synchronize相關(guān)信息都記錄在markword里面
偏向鎖默認打開
鎖升級過程
前面3種都屬于無鎖狀態(tài)
偏向鎖,同一個線程
輕量級鎖/自旋鎖,來了第二個線程,CAS操作
自旋次數(shù)過多(10)||線程超過cpu1/2 會消耗太多cpu 因此 會進行鎖升級成為重量級鎖
lockrecord里面記錄的hashcode
重量級鎖才是真的有鎖mutex,向內(nèi)核態(tài)申請,
重量級鎖有個隊列(無序,非公平鎖),在隊列里處于wait狀態(tài),不消耗CPU
偏向鎖有時延,可以通過參數(shù)改成0,默認4s
1.6以后自適應(yīng)


鎖降級只有在GC時才可以降級,除了GC線程沒有其他線程訪問,沒有意義,可以認為鎖降級不存在。

鎖粗化,可以把鎖加在whil外面

synchronized的最底層實現(xiàn)
也是 lock cmpxchg,volatile底層實現(xiàn)也是


緩存行
讀數(shù)據(jù)從外往里讀是按照塊讀,塊——cache line/緩存行,一次性也就是一行數(shù)據(jù) = 8字節(jié)
從內(nèi)存往cpu讀數(shù)據(jù),一塊一塊讀,一次讀64位,因為總線寬64bits
緩存行大都數(shù)是64字節(jié) bytes


cache line size = 8 字節(jié) cache size = 64字節(jié)

cpu層級的數(shù)據(jù)一致性是以緩存行為單位的
緩存行對齊優(yōu)化


CPU 緩存一致性協(xié)議 MESI(intel使用,其他的cpu可能用別的協(xié)議)

volatile
volatile解決了兩個問題:
可見性,
順序性(禁止指令重排序)
指令重排序

指令重排的實驗,正常情況 xy可能為01,10,11,但是不會出現(xiàn)00,亂序執(zhí)行結(jié)果出現(xiàn)了00

如何阻止亂序執(zhí)行?
jvm層面
cpu層面



線程1執(zhí)行了指令7 線程2執(zhí)行第一次判斷!=null直接返回版初始化的實例
指令重排序:單線程最終一致性就可以指令重排序。不考慮多線程情況。所以才需要加volatile。
OS通過加內(nèi)存屏障
java通過加關(guān)鍵字volatile,JVM看到指令后加屏障(4種,規(guī)范),c++通過lock實現(xiàn),只允許一條指令穿過總線

jvm四種引用
強:內(nèi)存不夠也不回收 OOM
軟若虛實際上有兩個引用 SoftReference<byte> b = new SoftReference<new byte[1024*1024*10 ]> b--new Soft...是強引用 new Soft...--new byte....才是軟引用,其他兩個同理
軟:緩存 eg.圖片,內(nèi)存不夠的時候回收掉
*弱:發(fā)生垃圾回收時直接回收。一次性。 Threadlocal,在spring事務(wù)有用到
threadlcoal用完后,key為null,value需要remove,否則還是會內(nèi)存泄漏


虛:虛引用get不到,跟沒有一樣,用處:管理對外內(nèi)存。NIO 零拷貝,直接操作os緩沖區(qū)數(shù)據(jù)。GC垃圾回收不會回收對外內(nèi)存,垃圾線程監(jiān)聽對jvm里面的內(nèi)存,被回收了就加緊queue,queue里面對應(yīng)的堆外內(nèi)存就會做相應(yīng)處理。






JVM禁止指令重排序的情況
happens-before規(guī)則
volatile實現(xiàn)





哈哈哈哈

浙公網(wǎng)安備 33010602011771號