JVM連載(2)

JMM Java內存模型:

1、 Java的并發采用“共享內存”模型,線程之間通過讀寫內存的公共狀態進行通訊。多個線程之間是不能通過直接傳遞數據交互的,它們之間交互只能通過共享變量實現。
2、 主要目的是定義程序中各個變量的訪問規則。
3、 Java內存模型規定所有變量都存儲在主內存中,每個線程還有自己的工作內存。
(1) 線程的工作內存中保存了被該線程使用到的變量的拷貝(從主內存中拷貝過來),線程對變量的所有操作都必須在工作內存中執行,而不能直接訪問主內存中的變量。
(2) 不同線程之間無法直接訪問對方工作內存的變量,線程間變量值的傳遞都要通過主內存來完成。
(3) 主內存主要對應Java堆中實例數據部分。工作內存對應于虛擬機棧中部分區域。

1532709451-5ad313f437a51.png

4、Java線程之間的通信由內存模型JMM(Java Memory Model)控制。
(1)JMM決定一個線程對變量的寫入何時對另一個線程可見。
(2)線程之間共享變量存儲在主內存中
(3)每個線程有一個私有的本地內存,里面存儲了讀/寫共享變量的副本。
(4)JMM通過控制每個線程的本地內存之間的交互,來為程序員提供內存可見性保證。
5、可見性、有序性:
(1)當一個共享變量在多個本地內存中有副本時,如果一個本地內存修改了該變量的副本,其他變量應該能夠看到修改后的值,此為可見性。
(2)保證線程的有序執行,這個為有序性。(保證線程安全)
6、內存間交互操作:
(1)lock(鎖定):作用于主內存的變量,把一個變量標識為一條線程獨占狀態。
(2)unlock(解鎖):作用于主內存的變量,把一個處于鎖定狀態的變量釋放出來,釋放后的變量才可以被其他線程鎖定。
(3)read(讀?。鹤饔糜谥鲀却孀兞浚阎鲀却娴囊粋€變量讀取到工作內存中。
(4)load(載入):作用于工作內存,把read操作讀取到工作內存的變量載入到工作內存的變量副本中
(5)use(使用):作用于工作內存的變量,把工作內存中的變量值傳遞給一個執行引擎。
(6)assign(賦值):作用于工作內存的變量。把執行引擎接收到的值賦值給工作內存的變量。
(7)store(存儲):把工作內存的變量的值傳遞給主內存
(8)write(寫入):把store操作的值入到主內存的變量中
6.1、注意:
(1)不允許read、load、store、write操作之一單獨出現
(2)不允許一個線程丟棄assgin操作
(3)不允許一個線程不經過assgin操作,就把工作內存中的值同步到主內存中
(4)一個新的變量只能在主內存中生成
(5)一個變量同一時刻只允許一條線程對其進行lock操作。但lock操作可以被同一條線程執行多次,只有執行相同次數的unlock操作,變量才會解鎖
(6)如果對一個變量進行lock操作,將會清空工作內存中此變量的值,在執行引擎使用這個變量前,需要重新執行load或者assgin操作初始化變量的值。
(7)如果一個變量沒有被鎖定,不允許對其執行unlock操作,也不允許unlock一個被其他線程鎖定的變量
(8)對一個變量執行unlock操作之前,需要將該變量同步回主內存中

堆的內存劃分:

2948191696-5ad31617eb2bd.png

Java堆的內存劃分如圖所示,分別為年輕代、Old Memory(老年代)、Perm(永久代)。其中在Jdk1.8中,永久代被移除,使用MetaSpace代替。
1、新生代:
(1)使用復制清除算法(Copinng算法),原因是年輕代每次GC都要回收大部分對象。新生代里面分成一份較大的Eden空間和兩份較小的Survivor空間。每次只使用Eden和其中一塊Survivor空間,然后垃圾回收的時候,把存活對象放到未使用的Survivor(劃分出from、to)空間中,清空Eden和剛才使用過的Survivor空間。
(2)分為Eden、Survivor From、Survivor To,比例默認為8:1:1
(3)內存不足時發生Minor GC
2、老年代:
(1)采用標記-整理算法(mark-compact),原因是老年代每次GC只會回收少部分對象。
3、Perm:用來存儲類的元數據,也就是方法區。
(1)Perm的廢除:在jdk1.8中,Perm被替換成MetaSpace,MetaSpace存放在本地內存中。原因是永久代進場內存不夠用,或者發生內存泄漏。
(2)MetaSpace(元空間):元空間的本質和永久代類似,都是對JVM規范中方法區的實現。不過元空間與永久代之間最大的區別在于:元空間并不在虛擬機中,而是使用本地內存。
4、堆內存的劃分在JVM里面的示意圖:


2866120826-5ad3196c98b32.png
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 工作之余,想總結一下JVM相關知識。 Java運行時數據區: Java虛擬機在執行Java程序的過程中會將其管理的...
    Huang遠閱讀 642評論 0 2
  • 一、運行時數據區域 Java虛擬機管理的內存包括幾個運行時數據內存:方法區、虛擬機棧、本地方法棧、堆、程序計數器,...
    luhanlin閱讀 556評論 0 0
  • java程序執行過程 運行時數據區域劃分 線程私有區域 1. 程序計數器: 1.1. 這塊內存區域很小,是當前線程...
    萍水相逢_程序員閱讀 505評論 0 1
  • Java內存區域 Java虛擬機在運行程序時會把其自動管理的內存劃分為以上幾個區域,每個區域都有的用途以及創建銷毀...
    架構師springboot閱讀 1,795評論 0 5
  • 《致迎春花》 好喜歡你純真的模樣 不大不小 不驕不媚 明亮而不耀眼 開了又開 笑臉盈盈 《致小花》 我不知你是桃還...
    青言倩語閱讀 360評論 0 6