【107期】談?wù)劽嬖嚤貑柕腏ava內(nèi)存區(qū)域(運(yùn)行時(shí)數(shù)據(jù)區(qū)域)和內(nèi)存模型(JMM)
閱讀本文大概需要 12?分鐘。
來自:www.cnblogs.com/czwbig/p/11127124.html
Java運(yùn)行時(shí)數(shù)據(jù)區(qū)域


由于 PermGen 內(nèi)存經(jīng)常會(huì)溢出,引發(fā)惱人的 java.lang.OutOfMemoryError: PermGen,因此 JVM 的開發(fā)者希望這一塊內(nèi)存可以更靈活地被管理,不要再經(jīng)常出現(xiàn)這樣的 OOM
移除 PermGen 可以促進(jìn) HotSpot JVM 與 JRockit VM 的融合,因?yàn)?JRockit 沒有永久代。根據(jù)上面的各種原因,PermGen 最終被移除,方法區(qū)移至 Metaspace,字符串常量移至 Java Heap。
引用自https://www.sczyh30.com/posts/Java/jvm-metaspace/
程序計(jì)數(shù)器
Java虛擬機(jī)棧

1. 局部變量表
2. 操作棧
棧中寫入和提取信息。JVM 的執(zhí)行引擎是基于棧的執(zhí)行引擎, 其中的棧指的就是操
作棧。字節(jié)碼指令集的定義都是基于棧類型的,棧的深度在方法元信息的 stack 屬性中。
i++:從局部變量表取出 i 并壓入操作棧,然后對(duì)局部變量表中的 i 自增 1,將操作棧棧頂值取出使用,最后,使用棧頂值更新局部變量表,如此線程從操作棧讀到的是自增之前的值。
++i:先對(duì)局部變量表的 i 自增 1,然后取出并壓入操作棧,再將操作棧棧頂值取出使用,最后,使用棧頂值更新局部變量表,線程從操作棧讀到的是自增之后的值。
3. 動(dòng)態(tài)鏈接
4.方法返回地址
正常退出,即正常執(zhí)行到任何方法的返回字節(jié)碼指令,如 RETURN、IRETURN、ARETURN 等;
異常退出。
返回值壓入上層調(diào)用棧幀。
異常信息拋給能夠處理的棧幀。
PC計(jì)數(shù)器指向方法調(diào)用后的下一條指令。
本地方法棧
Java堆
方法區(qū)
字符串存在永久代中,容易出現(xiàn)性能問題和內(nèi)存溢出。
類及方法的信息等比較難確定其大小,因此對(duì)于永久代的大小指定比較困難,太小容易出現(xiàn)永久代溢出,太大則容易導(dǎo)致老年代溢出。
永久代會(huì)為 GC 帶來不必要的復(fù)雜度,并且回收效率偏低。
將 HotSpot 與 JRockit 合二為一。
運(yùn)行時(shí)常量池
直接內(nèi)存

Java內(nèi)存模型
計(jì)算機(jī)高速緩存和緩存一致性

JVM主內(nèi)存與工作內(nèi)存

重排序和happens-before規(guī)則
編譯器優(yōu)化的重排序。編譯器在不改變單線程程序語義的前提下,可以重新安排語句的執(zhí)行順序。
指令級(jí)并行的重排序。現(xiàn)代處理器采用了指令級(jí)并行技術(shù)(Instruction-Level Parallelism, ILP)來將多條指令重疊執(zhí)行。如果不存在數(shù)據(jù)依賴性,處理器可以改變語句對(duì)應(yīng)機(jī)器指令的執(zhí)行順序。
內(nèi)存系統(tǒng)的重排序。由于處理器使用緩存和讀 / 寫緩沖區(qū),這使得加載和存儲(chǔ)操作看上去可能是在亂序執(zhí)行。

happens-before
程序順序規(guī)則:一個(gè)線程中的每個(gè)操作,happens- before 于該線程中的任意后續(xù)操作。
監(jiān)視器鎖規(guī)則:對(duì)一個(gè)監(jiān)視器鎖的解鎖,happens- before 于隨后對(duì)這個(gè)監(jiān)視器鎖的加鎖。
volatile 變量規(guī)則:對(duì)一個(gè) volatile 域的寫,happens- before 于任意后續(xù)對(duì)這個(gè) volatile 域的讀。
傳遞性:如果 A happens- before B,且 B happens- before C,那么 A happens- before C。

volatile關(guān)鍵字
保證此變量對(duì)所有線程的可見性。而普通變量不能做到這一點(diǎn),普通變量的值在線程間傳遞均需要通過主內(nèi)存來完成。
禁止指令重排序優(yōu)化。普通的變量?jī)H僅會(huì)保證在該方法的執(zhí)行過程中所有依賴賦值結(jié)果的地方都能獲取到正確的結(jié)果,而不能保證變量賦值操作的順序與程序代碼中的執(zhí)行順序一致。
推薦閱讀:
【106期】面試官:Java中的finally一定會(huì)被執(zhí)行嗎?
【105期】面試官:注冊(cè)中心全部宕掉后,Dubbo服務(wù)還能進(jìn)行調(diào)用嗎?
【103期】史上最全的數(shù)據(jù)庫面試題,面試前刷一刷!
微信掃描二維碼,關(guān)注我的公眾號(hào)
朕已閱?

