JVM系列【4】記憶體模型
阿新 • • 發佈:2020-10-11
## JVM系列筆記目錄
> - 虛擬機器的基礎概念
> - class檔案結構
> - class檔案載入過程
> - jvm記憶體模型
> - JVM常用指令
> - GC與調優
### 硬體層資料一致性
#### - 儲存器層次結構
![file](https://img2020.cnblogs.com/other/1295651/202010/1295651-20201011014108077-1425354914.jpg)
從L6-L0 空間由大變小,速度由慢到快。
#### -快取一致性演算法
CPU實現快取一致性的協議很多,其中intel 使用的MESI(Modified Exclusive Shared Or Invalid)協議。具體可以參考:[[MESI--CPU快取一致性協議](https://www.cnblogs.com/z00377750/p/9180644.html)](https://www.cnblogs.com/z00377750/p/9180644.html)
![file](https://img2020.cnblogs.com/other/1295651/202010/1295651-20201011014108883-1611103947.jpg)
現代CPU的資料一致性實現=快取鎖(MESI...) +匯流排鎖
#### -快取行
快取讀取時的單位,一般是64Byte
使用快取行的對齊能夠提高效率
#### -偽共享
位於同一快取行的2個不同的資料,被2個不同的CPU鎖定,產生互相影響的偽共享問題。
如何解決? 使用快取行的對齊能夠提高效率
#### CPU亂序問題
#### - 概念
CPU為了提高執行效率,會在一條指令執行的過程中(比如去記憶體取資料(慢100倍)),去同時執行另一條指令,前提是兩條指令沒有依賴關係。具體參考:[[現代cpu的合併寫技術對程式的影響](https://www.cnblogs.com/liushaodong/p/4777308.html)](https://www.cnblogs.com/liushaodong/p/4777308.html)
#### -合併寫
CPU上有一個WriteCombinBuffer,僅4個位元組,比L1等級還高,某些寫操作會合並在一起提交。[[現代cpu的合併寫技術對程式的影響](https://www.cnblogs.com/liushaodong/p/4777308.html)](https://www.cnblogs.com/liushaodong/p/4777308.html)
#### -亂序證明
CPU亂序現象有大佬寫程式模擬出來了,具體參考: [Memory Reordering Caught in the Act](https://preshing.com/20120515/memory-reordering-caught-in-the-act/)
#### 如何保證在特定情況下保證不亂序
#### 硬體級別
> X86 CPU級別記憶體屏障
>
> sfence
> store fence 在sfence指令前的寫操作必須在sfence指令後的寫操作前完成
>
> lfence
> load fence 在lfence指令前的讀操作必須在lfence指令後的讀操作前完成
>
> mfence
> mixed fence 在mfence指令前的讀寫操作必須在mfence指令後的讀寫操作前完成
>
> CPU原子指令
> 如x86上的”lock …” 指令是一個Full Barrier,執行時會鎖住記憶體子系統來確保執行順序,甚至跨多個CPU
>
> 總結: Software Locks通常使用了記憶體屏障或原子指令來實現變數可見性和保持程式順序
#### JVM級別
> JSR113規範規定了4種記憶體屏障
>
> LoadLoad屏障
> 對於語句Load1;LoadLoad;Load2,在Load2及後續讀取指令要讀取的資料被訪問前,保證Load1要讀取的資料被讀取完畢
>
> StoreStore屏障
> 對於語句Store1;StoreStore;Store2,在Store2及後續寫操作執行前,保證Store1的寫入操作對其它處理器可見
>
> LoadStore屏障
> 對於語句Load1;StoreStore;Store2,在Store2及後續寫操作被刷出前,保證Load1要讀取的資料被讀取完畢
>
> StoreLoad屏障
> 對於語句Store1;StoreStore;Load2,在Load2及後續讀取指令要執行前,保證Store1的寫入操作對其它處理器可見
#### sychronized/volatile在位元組碼、JVM、硬體OS層面實現細節
#### - sychronized
> - 位元組碼層面
>
> sychronized m() : AccessFlag : ACC_VOLATILE
>
> sychronized(this){} : monitorenter monitorexit monitorenter
>
> - JVM層面
>
> C/C++ 呼叫作業系統的同步操作
>
> - 硬體OS層面
>
> X86 : lock cmpxchg / xxx
#### -volatile
> - 位元組碼層面
> AccessFlag : ACC_VOLATILE
>
> - JVM層面
>
> volatile記憶體區域都加屏障
>
> StoreStoreBarrier volatile 寫操作 StoreLoadBarrier
>
> LoadLoadBarrier volatile 讀操作 LoadStoreBarrier
>
> - 硬體OS層面
>
> windows lock 指令實現 或是 MESI實現
### 面試new Object() 6連問
- 1.解釋物件的建立過程
該問題結合上篇部落格:[JVM系列【3】Class檔案載入過程](https://blog.csdn.net/qq_21579619/article/details/109001854)不難回答出來。
> class loading
>
> class linking (vertification prepraration resolution)
>
> class initiazing
>
> new 申請記憶體空間
>
> 成員變數賦初始值
>
> 呼叫構