java中JVM和JMM之間的區別


一 jvm結構

jvm的內部結構如下圖所示,這張圖很清楚形象的描繪了整個JVM的內部結構,以及各個部分之間的交互和作用。

1 Class Loader(類加載器)就是將Class文件加載到內存,再說的詳細一點就是,把描述類的數據從Class文件加載到內存,並對數據進行校驗、轉換解析和初始化,最終形成可以被虛擬機直接使用的Java類型,這就是類加載器的作用。

2 Run Data Area(運行時數據區) 就是我們常說的JVM管理的內存了,也是我們這里主要討論的部分。運行數據區是整個JVM的重點。我們所有寫的程序都被加載到這里,之后才開始運行。這部分也是我們這里將要討論的重點。

3 Execution engine(執行引擎) 是Java虛擬機最核心的組成部分之一。執行引擎用於執行指令,不同的java虛擬機內部實現中,執行引擎在執行Java代碼的時候可能有解釋執行(解釋器執行)和編譯執行(通過即時編譯器產生本地代碼執行,例如BEA JRockit),也有可能兩者兼備。任何JVM specification實現(JDK)的核心都是Execution engine,不同的JDK例如Sun 的JDK 和IBM的JDK好壞主要就取決於他們各自實現的Execution engine的好壞。

4 Native interface 與native libraries交互,是其它編程語言交互的接口。當調用native方法的時候,就進入了一個全新的並且不再受虛擬機限制的世界,所以也很容易出現JVM無法控制的native heap OutOfMemory。

二 Run Data Area(運行時數據區)

數據 描述
Program Counter Register 程序計數器,線程私有、指向下一條要很執行的指令
Java Stack Java虛擬機棧,線程私有,生命周期與線程相同。描述的是Java方法執行的內存模型:每個方法被執行的時候都會同時創建一個棧幀(Stack Frame)用於存儲局部變量表、操作棧、動態鏈接、方法出口
Native Method Stack 為虛擬機使用到的Native 方法服務
Heap 線程共享,由於現在收集器基本采用的分代收集算法,所以Java堆中還可以細分:新生代和老生代;更細致一點的有Eden空間、From Survivor空間、To Survivor空間等。所有的對象實例以及數組都要在堆上分配,是垃圾收集器管理的主要區域
Method Area 方法區,別名叫做非堆(Non-Heap),線程共享的內存區域。目的是與Java堆區分開來,存儲類信息、常量、靜態變量、即時編譯器編譯后的代碼。方法區存放的信息包括:A 類的基本信息:1.每個類的全限定名2.每個類的直接超類的全限定名(可約束類型轉換)3.該類是類還是接口4.該類型的訪問修飾符5.直接超接口的全限定名的有序列表B 已裝載類的詳細信息1.運行時常量池:在方法區中,每個類型都對應一個常量池,存放該類型所用到的所有常量,常量池中存儲了諸如文字字符串、final變量值、類名和方法名常量。它們以數組形式通過索引被訪 問,是外部調用與類聯系及類型對象化的橋梁。(存的可能是個普通的字符串,然后經過常量池解析,則變成指向某個類的引用)2.字段信息:字段信息存放類中聲明的每一個字段的信息,包括字段的名、類型、修飾符。字段名稱指的是類或接口的實例變量或類變量,字段的描述符是一個指示字段的類型的字符串,如private A a=null;則a為字段名,A為描述符,private為修飾符。3.方法信息:類中聲明的每一個方法的信息,包括方法名、返回值類型、參數類型、修飾符、異常、方法的字節碼。(在編譯的時候,就已經將方法的局部變量、操作數棧大小等確定並存放在字節碼中,在裝載的時候,隨着類一起裝入方法區。)4.靜態變量:就是類變量,類的所有實例都共享,我們只需知道,在方法區有個靜態區,靜態區專門存放靜態變量和靜態塊。5.到類classloader的引用:到該類的類裝載器的引用。6.到類class 的引用:jvm為每個加載的類型(譯者:包括類和接口)都創建一個java.lang.Class的實例。而jvm必須以某種方式把Class的這個實例和存儲在方法區中的類型數據聯系起來。

三 jmm

Java內存模型(Java Memory Model,JMM)JMM主要是為了規定了線程和內存之間的一些關系。根據JMM的設計,系統存在一個主內存(Main Memory),Java中所有變量都儲存在主存中,對於所有線程都是共享的。每條線程都有自己的工作內存(Working Memory),工作內存中保存的是主存中某些變量的拷貝,線程對所有變量的操作都是在工作內存中進行,線程之間無法相互直接訪問,變量傳遞均需要通過主存完成。

四 jvm和jmm之間的關系

jmm中的主內存、工作內存與jvm中的Java堆、棧、方法區等並不是同一個層次的內存划分,這兩者基本上是沒有關系的,如果兩者一定要勉強對應起來,那從變量、主內存、工作內存的定義來看,主內存主要對應於Java堆中的對象實例數據部分,而工作內存則對應於虛擬機棧中的部分區域。從更低層次上說,主內存就直接對應於物理硬件的內存,而為了獲取更好的運行速度,虛擬機(甚至是硬件系統本身的優化措施)可能會讓工作內存優先存儲於寄存器和高速緩存中,因為程序運行時主要訪問讀寫的是工作內存。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM