前言
可跟《主存存取和磁盤存取原理筆記》串着看java
http://www.javashuo.com/article/p-ezyduzdz-w.html緩存
雜技
Java 內存模型(堆棧)
Jvm 內部,Java 內存模型把內存分紅了兩個部分:線程棧區和堆區:
棧區包含:線程執行信息(線程棧),本地原始類型變量(boolean,byte, short, int, long, float, double)
堆區包含:Java 應用建立的全部對象信息,基礎類型的封裝類
架構
- 一個本地變量若是是原始類型,存儲棧中
- 一個本地變量是一個對象的引用,那麼這個本地引用存儲棧,對象自己存儲堆中
- 一個對象的成員方法,存儲棧中,方法中包含的原始類型變量,存儲堆中
- 一個對象的成員變量,不管是原始類型仍是包裝類型,都存儲堆中
- 堆中數據可被多個線程共享,對於原始類型變量,每一個線程都會拷貝一份
硬件內存架構
無論什麼內存模型,最終仍是運行在計算機硬件上,所以有必要了解計算機硬件的內存架構 優化
- 如今計算機通常都有2個以上cpu, 每一個cpu還有多個核心,線程會在各個cpu核心中並行運行
- CPU 內部會有一組CPU 寄存器、CPU 緩存(一級,二級,三級緩存),RAM主存
- 存儲速度: CPU 寄存器 > CPU 緩存(一級> 二級> 三級) > RAM
- 存儲大小 CPU 寄存器(64 bit) < CPU 緩存[一級(64k)> 二級(256k)> 三級(8MB)] < RAM(4G)
線程間的競爭現象
- 存在 count 爲1, 兩個線程都在緩存中保存一份備份
- 兩個線程分別改變 count 的值,存在寫緩存,顧緩存和 RAM的值存在誤差
- 當寫緩存的數據 flush 到 RAM 就發生衝突了
內存屏障(Memory Barrier):
- 內存屏障,又稱內存柵欄,是一個CPU 指令
- 保證特定操做的執行順序。編譯器和CPU會重排序指令,爲了優化,插入內存屏障指令會讓CPU不把這條指令重排序。
- 影響某些數據(或某條指令的執行結果)的內存可見性。強制刷新各類CPU cache, 寫緩存的數據直接寫入RAM,讀緩存從新讀取數據
內存屏障和 Java 有什麼關係?
volatile 是基於 Memory Barrier 實現的。ui
這意味着,若是寫入一個 volatile 變量a,能夠保證:.net
- 一個線程寫入變量a 後,任何線程訪問該變量都會拿到最新值
- 因爲會刷新 Cache中全部先前寫入,所以寫入變量a以前的寫入操做,其更新的數據對於其它線程也是可見的