JVM从入门到精通(四):内存屏障与JVM指令,对象的内存布局
JMM
硬件層數據一致性
協議很多,intel 用MESI
https://www.cnblogs.com/z00377750/p/9180644.html
現代CPU的數據一致性實現 = 緩存鎖(MESI …) + 總線鎖
讀取緩存以cache line為基本單位,目前64bytes
位于同一緩存行的兩個不同數據,被兩個不同CPU鎖定,產生互相影響的偽共享問題
偽共享問題:JUC/c_028_FalseSharing
使用緩存行的對齊能夠提高效率
亂序問題
CPU為了提高指令執行效率,會在一條指令執行過程中(比如去內存讀數據(慢100倍)),去同時執行另一條指令,前提是,兩條指令沒有依賴關系
寫操作也可以進行合并
https://www.cnblogs.com/liushaodong/p/4777308.html
JUC/029_WriteCombining
亂序執行的證明:JVM/jmm/Disorder.java
原始參考:https://preshing.com/20120515/memory-reordering-caught-in-the-act/
如何保證特定情況下不亂序
硬件內存屏障,針對X86:
sfence: store| 在sfence指令前的寫操作當必須在sfence指令后的寫操作前完成。
lfence:load | 在lfence指令前的讀操作當必須在lfence指令后的讀操作前完成。
mfence:modify/mix | 在mfence指令前的讀寫操作當必須在mfence指令后的讀寫操作前完成。
原子指令,如x86上的”lock …” 指令是一個Full Barrier,執行時會鎖住內存子系統來確保執行順序,甚至跨多個CPU。Software Locks通常使用了內存屏障或原子指令來實現變量可見性和保持程序順序
JVM級別如何規范(JSR133)
LoadLoad屏障:
對于這樣的語句Load1; LoadLoad; Load2,
在Load2及后續讀取操作要讀取的數據被訪問前,保證Load1要讀取的數據被讀取完畢。
StoreStore屏障:
對于這樣的語句Store1; StoreStore; Store2
在Store2及后續寫入操作執行前,保證Store1的寫入操作對其它處理器可見。
LoadStore屏障:
對于這樣的語句Load1; LoadStore; Store2,
在Store2及后續寫入操作被刷出前,保證Load1要讀取的數據被讀取完畢。
StoreLoad屏障:
對于這樣的語句Store1; StoreLoad; Load2,
在Load2及后續所有讀取操作執行前,保證Store1的寫入對所有處理器可見。
volatile 的實現細節
字節碼層面
ACC_VOLATILE
JVM層面
對于volatile內存區的讀寫,都加屏障:
StoreStoreBarrier
volatile 寫操作
StoreLoadBarrier
LoadLoadBarrier
volatile 讀操作
LoadStoreBarrier
OS和硬件層面
https://blog.csdn.net/qq_26222859/article/details/52235930
使用hsdis工具 - HotSpot Dis Assembler
windows lock 指令實現 | MESI實現
synchronized實現細節
ACC_SYNCHRONIZED
monitorenter monitorexit
C C++ 調用了操作系統提供的同步機制,在win和linux上不同
X86 : lock cmpxchg / xxx
lock是處理多處理器之間的總線鎖問題
https://blog.csdn.net/21aspnet/article/details/88571740
使用synchronized的例子:
生成的JVM指令:
Java并發內存模型
as-if-serial
? 不管如何重排序,單線程執行結果不會改變,看起來像是串行的一樣
對象的內存布局
觀察虛擬機配置
java -XX:+PrintCommandLineFlags -version
-XX:InitialHeapSize=266536512 -XX:MaxHeapSize=4264584192 -XX:+PrintCommandLineFlags -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:-UseLargePagesIndividualAllocation -XX:+UseParallelGC java version "1.8.0_241" Java(TM) SE Runtime Environment (build 1.8.0_241-b07) Java HotSpot(TM) 64-Bit Server VM (build 25.241-b07, mixed mode)對象在內存中的存儲布局?
(經過試驗證明)一個Object是16字節,8(對象頭)+4(開啟壓縮時的對象指針)+padding(對齊)
普通對象
Oops Ordinary Object Pointers
數組對象
對象頭具體包括什么?
問題:為什么GC年齡默認為15?因為分代年齡只有4bit,可以表示最大的數就是15
當一個對象計算過identityHashCode之后,不能進入偏向鎖狀態
對象怎么定位?
https://blog.csdn.net/clover_lily/article/details/80095580
《深入理解Java虛擬機》
對象在內存中的哪個區域,分配過程
總結
以上是生活随笔為你收集整理的JVM从入门到精通(四):内存屏障与JVM指令,对象的内存布局的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MySQL调优(三):索引基本实现原理及
- 下一篇: 多线程与高并发(五):强软弱虚四种引用以