JVM系列【4】內存模型

JVM系列筆記目錄

  • 虛擬機的基礎概念
  • class文件結構
  • class文件加載過程
  • jvm內存模型
  • JVM經常使用指令
  • GC與調優

硬件層數據一致性

- 存儲器層次結構

file

從L6-L0 空間由大變小,速度由慢到快。html

-緩存一致性算法

CPU實現緩存一致性的協議不少,其中intel 使用的MESI(Modified Exclusive Shared Or Invalid)協議。具體能夠參考:[MESI--CPU緩存一致性協議](http://www.javashuo.com/article/p-nemwwelp-he.html)面試

file

現代CPU的數據一致性實現=緩存鎖(MESI...) +總線鎖算法

-緩存行

緩存讀取時的單位,通常是64Byte
使用緩存行的對齊可以提升效率windows

-僞共享

位於同一緩存行的2個不一樣的數據,被2個不一樣的CPU鎖定,產生互相影響的僞共享問題。數組

如何解決? 使用緩存行的對齊可以提升效率緩存

CPU亂序問題

- 概念

CPU爲了提升執行效率,會在一條指令執行的過程當中(好比去內存取數據(慢100倍)),去同時執行另外一條指令,前提是兩條指令沒有依賴關係。具體參考:[現代cpu的合併寫技術對程序的影響](http://www.javashuo.com/article/p-mouhfepk-gc.html)jvm

-合併寫

CPU上有一個WriteCombinBuffer,僅4個字節,比L1等級還高,某些寫操做會合並在一塊兒提交。[現代cpu的合併寫技術對程序的影響](http://www.javashuo.com/article/p-mouhfepk-gc.html)佈局

-亂序證實

CPU亂序現象有大佬寫程序模擬出來了,具體參考: Memory Reordering Caught in the Actthis

如何保證在特定狀況下保證不亂序

硬件級別

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文件加載過程不難回答出來。

    class loading

    class linking (vertification prepraration resolution)

    class initiazing

    new 申請內存空間

    成員變量賦初始值

    調用構造方法 :成員變量賦初始值;執行構造方法語句,super()父類構造。

  • 2.對象在內存中的存儲佈局

    對象在內存中佈局分普通對象和數組對象。

    普通對象4部分:對象頭markword(8字節)、ClassPointer指針(4或8字節)、實例數據、padding對齊爲8的倍數。

    數組對象5部分,和普通對象相似,但中間是數組長度4字節和具體的數組數據。

file

  • 3.對象頭具體包括什麼

    對象頭markword(8字節)具體內容和對象鎖狀態有關係,其中最高位2位是鎖狀態中,最低3位用做鎖標誌位,中間4位是GC年齡,以下。

  • 4.對象怎麼定位

    經過句柄池和直接指針,具體參考:訪問對象兩種方式--句柄和直接指針

  • 5.對象怎麼分配?

    對象的分配其實和垃圾回收GC有關係,後續總結GC詳細講。

file

  • 6.Object o = new Object() 在內存中的佔用多少個字節

    16個字節,根據第2點的內存佈局能夠算出。

知識分享,轉載請註明出處。學無前後,達者爲先!

相關文章
相關標籤/搜索