關於Java中的內存屏障


如何打破雙親委派機制

繼承ClassLoader類后重寫loadClass方法

如何指定自定義ClassLoader中的parent

默認parent是appClassLoader,可以通過ClassLoader構造方法指定

存儲器的層器結構

為什么要緩存行對齊

有多個CPU或者多個核,他們都有自己的高速緩存,但是高速緩存都是先從內存中的L3高速緩存中讀數據,每次讀一行也就是64字節。所以當多個CPU或者多個核從L3高速緩存中讀了同一緩存行到他們內部的高速緩存中,當有一個CPU或核修改了緩存行中的數據,由於緩存一致性協議,會把新的數值寫會到內存中,並且其他CPU或者核會把這個數據標記為失效轉態,會重新從內存中讀取。這樣當我們想操作一個數據m的時候,就可以在這個數據m前后多創建幾個對象,確保其他線程要操作數據n不在m所在的緩存行中,避免當大量修改m值得時候,其他線程需要反復去內存中重新讀取這個緩存行。

如何實現緩存一致性

  1. 使用緩存鎖(MESI): 用四種標記每個cache line的狀態。有時有些無法緩存的數據或者跨越多個緩存行的數據用總線鎖)
  2. 使用總線鎖

CPU指令並寫

當有多個指令進行寫操作時,可以把這些指令先做完再寫回內存。

當進行並寫時,會把指令完成后的結果存入到一個WriteCombingBuffer,它類似於一個數組,但只有4個位置,並且它的速度比高速緩存還要快。當里面4個位置都被裝滿后就會寫回L2。

硬件、內存級別如何實現內存屏障

sfence指令:表示執行sfence指令之前的寫操作一定要在sfence指令之后的寫操作之前完成。

lfence指令:同理

mfence指令

JVM級別中的規范

  1. LoadLoad屏障

    對於 Load1; LoadLoad; Load2這樣的語句

    要保證Load2讀取之前,Load1已讀取完畢。

  2. LoadStore屏障

    同理

  3. StoreLoad屏障

  4. StoreStore屏障

volatile實現細節

  1. 字節碼層面

    在Access flags中會標記為 volatitle

  2. JVM層面

    在對Volatitle內存區進行讀寫時,都加屏障

    StoreStore 屏障

    Volatitle寫操作

    StoreLoad 屏障

    LoadLoad 屏障

    Volatitle 讀操作

    LoadStore 屏障

  3. OS和硬件層面

    lock指令

Synchronized實現細節

  1. 字節碼層面

    1. 如果寫在方法上 Access flags 會標記這個方法為 synchronized

    2. 如果寫在代碼塊上,會用兩個指令實現

      monitorenter moniterexit

  2. JVM層面

    會調用C/C++寫的調用操作系統的同步機制

  3. OS和硬件層面

    X86中: lock comxchg ...

參考:

https://blog.csdn.net/21aspnet/article/details/88571740

https://blog.csdn.net/qq_26222859/article/details/52235930


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM