1、JVM由字節碼執行引擎、類裝載子系統、運行時數據區組成。c++
1.類裝載子系統主要是把class文件加載到運行時數據區中,算法
2.字節碼執行引擎主要是執行字節碼文件,並把執行的相應的行數數據推送到運行時數據區中的程序計數器中jvm
3.運行時數據區是文件執行的主要場所。spa
2、運行時數據區由下面幾個區域構成:線程
1.堆:大多數對象建立以後都放在堆中,少數放在棧中指針
2.棧:每一個線程產生都會有一個獨有的線程棧(在棧上分的一小塊內存),棧的主要做用是爲程序運行提供場所,即程序的執行操做在棧中進行對象
3.本地方法棧:存放一些執行本地方法的地址指針,主要是一些早期的c++執行的本地方法blog
4.程序計數器:記錄程序運行的位置,若是被打斷以後能夠接着打斷的地方接着運行內存
5.方法區(元空間):存放一些靜態變量、類元信息等字符串
元空間和堆是全部執行文件所共享的區域,即一個靜態變量被建立以後能夠被另外一個線程所引用
而每個線程都有本身的其餘區域,即線程棧、程序計數器和本地方法棧,線程結束後即被銷燬
3、分別介紹:
1.堆(垃圾回收機制):堆分爲年輕代和老年代,空間大小爲1:2,年輕代又分爲eden區和survivor區,比例爲8:1:1,以上兩個比例皆能夠修改
對象在被建立後放入Eden區中,當Eden區放滿以後,會進行一次minor gc,經過可達性算法分析,將垃圾對象進行回收,而後將不是垃圾的對象放入survivor1區中,通過程序執行以後,若是eden區再次放滿,則會將Eden區和survivor1區中的對象進行垃圾回收,將仍然存活的對象放入survivor2區中,即每次進行垃圾回收後的對象都放在另外一個survivor區中,直到對象的分帶年齡達到設定值以後(默認爲15,由於對象中的分代年齡指針佔四個字節,最大值爲15),放入老年代,其中,對象每經歷一次minor gc,分代年齡就會加一。老年代通過屢次minor gc後,也會放滿,若是老年代放滿,程序會進行full gc,即,程序會進行STW(stop the ),即終止程序運行,而後經過可達性分析算法,進行一次full gc。若是對象仍然存活,則繼續存放在老年代中,若是老年代的對象full gc以後仍然滿了,則會出現內存溢出的錯誤狀況。
2.棧:
棧是程序運行的主要場所,每有一個線程運行時,jvm就會給這個線程在棧上分配一塊獨立的區域(線程棧)去存放本身的局部變量,線程棧的主要由棧幀組成,每一個方法都有一個獨立的棧幀,棧幀上主要有:方法出口、動態連接、操做數棧、局部變量表組成。好比執行main方法,則main方法有本身獨立的棧和本地方法棧以及程序計數器,根據程序計數器,來進行記錄執行的位置,經過字節碼執行引擎進行執行,執行main方法時,會給main方法生成一個獨立的棧幀,棧幀中本地變量區域放入方法中生成的局部變量,對局部變量進行操做時,將局部變量放入操做數棧中(局部變量作操做時用來中轉存放的內存空間),當執行操做時,將操做數棧中的數據順序出棧,放入外部寄存器中,用運算器進行運算,運算出來結果以後再把值放入操做數棧中,再進行賦值給本地變量。動態連接:程序在加載時,在解析階段只會進行靜態連接(將符號引用替換爲直接引用,該階段會把一些靜態方法(符號引用,好比main()方法)替換爲指向數據所存內存的指針或句柄等(直接引用),這是所謂的靜態連接過程(類加載期間完成),動態連接是在程序運行期間完成的將符號引用替換爲直接引用,下節課會講到動態連接),即只解析靜態方法,當程序運行到靜態方法中的普通方法時,會進行動態連接。由於程序在加載階段會把編譯爲一條條指令文件,而後存放在元空間的常量池中,因此在執行動態連接時,即是找到該方法的在元空間常量池的地址。方法出口:一個方法運行完成以後返回到上層調用方法的哪個位置。若是方法中引用對象信息,則對應點局部變量表中保存的是堆中對象的地址指針。
3.程序計數器:
記錄程序運行的位置,若是程序暫停,再從新開始後,程序會從程序計數器的位置開始執行,程序計數器的位置是外部字節碼執行引擎執行發送的地址。
4.本地方法棧:
存放一些本地底層的方法。
5.方法區(元空間):
存放靜態變量、字符串常量池、對象常量池、類元信息等。靜態變量:文件在加載過程當中,在準備階段對一些靜態變量進行分配空間,並賦予默認值,在初始化階段再進行賦初始值。常量池:存放相應信息。類元信息:文件在加載過程當中,在加載階段,文件會編譯爲字節碼文件,其中,相應的類中的方法、變量等相應的信息爲類元信息。靜態變量是對象類型,則存放指向該對象在堆中的地址。
4、相互之間的聯繫:
經過類裝載子系統進行裝載類,而後經過字節碼執行引擎進行執行,執行main()方法時,在棧中劃分一小部分空間生成線程棧,在線程棧中爲main方法生成獨立棧幀,若是類中有其餘方法,則生成一個新的棧幀,在棧幀中的局部變量表中存放執行過程當中的局部變量,在操做數棧中進行對操做數進棧以及出棧,而後在外部執行運算,在賦值給本地變量,其中執行步驟都是由該線程獨有的程序計數器計數執行位置供字節碼執行引擎執行。若是棧幀中局部變量爲對象類型,則局部變量表中存放的是堆中對象的指針地址。該對象頭中存在指針,指向其所屬的類,也就是指向方法區中該類的地址。當一個類加載到jvm中會產生類對象,即在堆中存放的class對象,方法區中的類元信息會再次指向堆中的class類對象。
若是方法區(元空間)中靜態變量是對象類型,則方法區(元空間)的常量池中存放指向該對象在堆中的地址。