java虛擬機JVM

 

類裝載器的分類(ClassLoader):           ①BootStap,根裝載器
(類裝載器負責加加載class文件,class     ②ExtClassLoader,擴展類裝載器
 文件在開頭 有特定的文件表示)               ③ApplicationClassLoader,應用類裝載器 
                                                                 ④自定義裝載器
 
雙親委派機制:當一個類收到類加載請求,他首先不會嘗試本身去加載這個類,而是把這請求委派給父類去完成,每個層次類加載器都是如此,所以全部的加載請求都應該傳送到啓動類加載器中,只有當父類加載器反饋本身沒法完成這個請求的時候(在它的加載路徑下沒有找到所需加載的Class),子類加載器纔會嘗試本身去加載。
 
沙箱安全機制:沙箱機制就是將Java代碼限定在虛擬機(JVM)特定的運行範圍中,而且嚴格限制代碼對本地系統資源訪問,經過這樣的措施來保證對代碼的有效隔離,防止對本地系統形成破壞。
(1)類加載器:①它防止惡意代碼區干涉善意的代碼②它守護了被信任的類庫邊界③它將代碼納入保護域,該域決定了代碼能夠進行哪些操做
(2)Class文件檢驗器:Class文件檢驗器保證裝載的class文件內容的內部結構的正確,而且這些class文件相互協調一致。Class文件檢驗器實現的安全目標之一就是程序的健壯性,JAVA虛擬機的class文件檢驗器要進行四趟掃描來文成他的操做(第一趟:在裝載字節序列的時候進行,這個是校驗class文件結構的合法性;第二趟:掃描發生在方法區中,主要對於語義、語法和詞法的分析;第三趟:字節碼校驗字節碼流=操做碼+操做數;第四趟:符號引用的校驗)
 
Execution Engine執行引擎:負責解釋命令,提交操做系統執行。
 
Native Interface本地接口:做用是融合不一樣的編程語言爲Java所用,在內存中開闢了一塊區域處理標記爲native的代碼,具體作法是Native Method Stack中登記native方法,在Execution Engine執行時加載native libraies,在企業級應用中已經比較少見,
 
Native Method Stack:具體作法是Native Method Stack中登記native方法,在Execution Engine執行時加載本地方法庫。
 
Program Counter Register(PC計數器):每一個線程都有一個程序計數器,是線程私有的,就是一個指針,指向方法區中的方法字節碼(用來儲存指向下一條指令的地址,也即將要執行的指令代碼),由執行引擎讀取下一條指令,是一個很是小的內存空間,幾乎能夠忽略不記。它是當前線程所執行的字節碼的行號指示器,字節碼解釋器經過改變這個計數器的值來選取下一條須要執行的字節碼指令。若是執行的是一個Native方法,這個計數器是空的。
 
Method Area(方法區):供各線程共享的運行時內存區域。它儲存除了每個類的結構信息,例如運行時常量池、字段和方法數據、構造函數和普通方法的字節碼內容。還儲存靜態方法、靜態內部類和靜態變量(static);
方法區是規範,在不一樣的虛擬機裏面實現是不同的,最典型的就是(PermGen space)永久代和以(Metaspace)元空間
 
棧管運行
堆管存儲
 
Stack棧:儲存的是8種基本類型的變量、對象的應用變量和實例方法。
即①本地變量:輸入參數和輸出參數以及方法內的變量
   ②棧操做:記錄出棧、入棧的操做
   ③棧幀數據:包括類文件、方法等
棧運行遵循「先進先出」、「後進後出」原則
每一個方法執行的同時都會建立一個棧幀,用於存儲局部變量表、操做數棧、動態鏈接、方法出口等信息,每個方法從調用直至執行完畢的過程,就對應着一個棧幀在虛擬機中入棧到出棧的過程/棧的大小和具體JVM有關,一般在256k-756k之間,約等於1mb。
 
經過指針的方式來訪問對象,棧中存放基本數據類型以及應用變量,指向堆中存放的實例對象,java堆中存放訪問類元數據的地址,方法區中存放對象的類的類對象
 
Heap(堆):一個JVM實例只存在一個堆內存,堆內存的大小是能夠調節的,類加載器讀取了;類文件後,須要把類、方法、常變量放到堆內存中,保存全部引用類型的真實信息,以方便執行器執行。
新生區:是類的誕生、生長、消亡的區域,一個類在這裏產生,應用,最後被垃圾回收器收集,結束生命。新生區又分爲兩部分:伊甸區(Eden space)和倖存者區(Survicor space),全部的類都是在伊甸區被new出來的。倖存區有兩個:0區(Survivor 0 space)和1區(Survivor 1 space).當伊甸園區的空間用完時,程序又要建立對象,JVM的垃圾回收器將對伊甸園區進行垃圾回收(Minor GC),將伊甸園區中的再也不被其餘對象所引用的對象進行銷燬。而後將伊甸園中的剩餘對象移動到倖存者0區,若倖存者0區也滿了,再對該區進行垃圾回收,而後移動到1區,1區滿了,移動到養老區。若養老區也滿了,那麼這個時候將產生Major GC(FullGC),進行養老區的內存清理。若養老區執行了Full GC後依然沒法進行對象的保存,就會產生OOM異常「OutOfMemoryError」。
若是出現java.lang.OutOfMemoryError:Java heap space 異常,說明Java虛擬機的堆內存不夠。緣由有二:(1)Java虛擬機的堆內存設置不夠,能夠經過參數-Xms、-Xmx來調整
                 (2)代碼中建立了大量大對象,而且長時間不能被垃圾收集器收集(存在被引用)
 
 
MinorGC的過程(複製 -> 清空 -> 互換)
堆內存中,新生代和老年代的比例爲1/3和2/3
 
1:eden、SurvivorFrom 複製到 SurvivorTo,年齡+1
在新生代中,Eden所佔比例爲8/10,倖存者0區和倖存者1區的比例至關,爲1/10
Eden滿的時候,出發第一次GC,將活着的對象拷貝到from區,清空Eden區,存新的對象,放Eden再次觸發GC的時候會掃描Eden區和From區,對這兩個區進行垃圾回收,通過此次回收還存活的對象,會直接複製到To區(若是有對象的年齡已經達到了老年的標準,複製到老年區),同時把這些對象的年齡+1.
2:清空 eden、SurvivorFrom
From和Eden中的數據複製到To中後,發生交換,From爲空,轉爲To,To轉爲From
3:SurvivorTo和 SurvivorFrom 互換 
最後,SurvivorTo和SurvivorFrom互換,原SurvivorTo成爲下一次GC時的SurvivorFrom區。部分對象會在From和To區域中複製來複制去,如此交換15次(由JVM參數MaxTenuringThreshold決定,這個參數默認是15),最終若是仍是存活,就存入到老年代
 
方法區(Method Area)和堆同樣,是各個線程共享的內存區域,它用於存儲虛擬機加載的:類信息+普一般量+靜態常量+編譯器編譯後的代碼等等,雖然JVM規範將方法區描述爲堆的一個邏輯部分,但它卻還有一個別名叫作Non-Heap(非堆),目的就是要和堆分開。
jdk1.7的版本中,已經將本來放在永久代的字符串常量池移走。
java7以前的永久區,是一個常駐內存區域,用於存放JDK自身所攜帶的Class,Interface的元數據,也就是說它存儲的是運行環境必須的類信息,被裝載進此區域的數據是不會被垃圾回收器回收掉的,關閉JVM纔會釋放此區域所佔用的內存。
 
Java8以後將永久代取消了,由元空間取代。本質和永久代相似。最大的區別在於:永久代使用的JVM的堆內存,可是Java8後的元空間並不在虛擬機中,而是使用本地物理內存。
 
JVM調優
-Xms初始分配大小爲:物理內存的1/64
-Xmx最大分配內存爲:物理內存的1/4
VM參數:    -Xms1024m -Xmx1024m -XX:+PrintGCDetails
 
相關文章
相關標籤/搜索