JAVA內存模型JMM分析

JMM是Java Memory Model的縮寫,也就是我們面試中常提到的JAVA內存模型,這塊內容比較多,我也不知道能不能把這塊關係理清楚,暫且先看吧,如果發現問題,請及時聯繫我修改,免得誤導別人。

1.Java內存結構

java內存圖.png

Java虛擬機在運行程序時會把其自動管理的內存劃分爲以上幾個區域,每個區域都有的用途以及創建銷燬的時機,其中藍色部分代表的是所有線程共享的數據區域,而綠色部分代表的是每個線程的私有數據區域。

方法區(Method Area):

方法區屬於線程共享的內存區域,又稱Non-Heap(非堆),主要用於存儲已被虛擬機加載的類信息、常量、靜態變量、即時編譯器編譯後的代碼等數據,根據Java 虛擬機規範的規定,當方法區無法滿足內存分配需求時,將拋出OutOfMemoryError 異常。值得注意的是在方法區中存在一個叫運行時常量池(Runtime Constant Pool)的區域,它主要用於存放編譯器生成的各種字面量和符號引用,這些內容將在類加載後存放到運行時常量池中,以便後續使用。

JVM堆(Java Heap):

Java 堆也是屬於線程共享的內存區域,它在虛擬機啓動時創建,是Java 虛擬機所管理的內存中最大的一塊,主要用於存放對象實例,幾乎所有的對象實例都在這裏分配內存,注意Java 堆是垃圾收集器管理的主要區域,因此很多時候也被稱做GC 堆,如果在堆中沒有內存完成實例分配,並且堆也無法再擴展時,將會拋出OutOfMemoryError 異常。

程序計數器(Program Counter Register):

屬於線程私有的數據區域,是一小塊內存空間,主要代表當前線程所執行的字節碼行號指示器。字節碼解釋器工作時,通過改變這個計數器的值來選取下一條需要執行的字節碼指令,分支、循環、跳轉、異常處理、線程恢復等基礎功能都需要依賴這個計數器來完成。

虛擬機棧(Java Virtual Machine Stacks):

屬於線程私有的數據區域,與線程同時創建,總數與線程關聯,代表Java方法執行的內存模型。每個方法執行時都會創建一個棧楨來存儲方法的的變量表、操作數棧、動態鏈接方法、返回值、返回地址等信息。每個方法從調用直結束就對於一個棧楨在虛擬機棧中的入棧和出棧過程,如下(圖有誤,應該爲棧楨):

本地方法棧(Native Method Stacks):

本地方法棧屬於線程私有的數據區域,這部分主要與虛擬機用到的 Native 方法相關,一般情況下,我們無需關心此區域。

這裏之所以簡要說明這部分內容,注意是爲了區別Java內存模型與Java內存區域的劃分,畢竟這兩種劃分是屬於不同層次的概念。


Java內存模型概述

Java內存模型(即Java Memory Model,簡稱JMM)本身是一種抽象的概念,並不真實存在,它描述的是一組規則或規範,通過這組規範定義了程序中各個變量(包括實例字段,靜態字段和構成數組對象的元素)的訪問方式。由於JVM運行程序的實體是線程,而每個線程創建時JVM都會爲其創建一個工作內存(有些地方稱爲棧空間),用於存儲線程私有的數據,而Java內存模型中規定所有變量都存儲在主內存,主內存是共享內存區域,所有線程都可以訪問,但線程對變量的操作(讀取賦值等)必須在工作內存中進行,首先要將變量從主內存拷貝的自己的工作內存空間,然後對變量進行操作,操作完成後再將變量寫回主內存,不能直接操作主內存中的變量,工作內存中存儲着主內存中的變量副本拷貝,前面說過,工作內存是每個線程的私有數據區域,因此不同的線程間無法訪問對方的工作內存,線程間的通信(傳值)必須通過主內存來完成。

這塊資料太多,還未完善,最近離職了,下次繼續完善,見諒。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章